(BCCing security-dev@)
# Contact emails
# Spec
# Summary
We'll begin requiring servers on a user's local machine (127.0.0.1) or intranet (as defined by RFC1918) to explicitly opt-in to connections originating from the public internet. This boils down to two concrete changes:
1. We'll require a CORS preflight for requests from "the internet" to "the intranet"*. Along with all the usual headers, this preflight will have a new request header ("Access-Control-Request-External") which signals to the receiving server that the request originated outside of the intranet. In order to pass the CORS check, the response to the preflight must contain a new response header ("Access-Control-Allow-External") with a value of "true".
2. We'll entirely deny non-secure origins on "the internet" the ability to make requests to "the intranet".
* RFC1918 is a good start, but especially in the world of IPv6, "the internet" and "the intranet" aren't entirely straightforward to define. Part of the implementation work will be to solidify definitions that we're comfortable with.
# Motivation
The user agent is in a privileged position on a user's local network, and folks out there on the internet use that position to access servers they'd otherwise be prevented from obtaining. This happens far more often than I'd expected: ~0.9% of page views during the week, ~0.5% of page views on the weekends (
https://www.chromestatus.com/metrics/feature/timeline/popularity/530). Killing these connections outright is infeasible, and developers have come up with clever ways of using the capability to make interesting experiences for users.
The changed proposed here will make these kinds of attacks more difficult in two ways:
1. Devices which do not intend to talk to the internet will not be exposed to that attack surface by default. If your printer doesn't explicitly opt-in, all it will see is an OPTIONS request. Anecdotally, these requests are dropped on the floor.
2. Servers which do intend to talk to the internet will make explicit decision about which origins are granted access. Your router's exciting configuration pages might choose to expose themselves to `
router.com`, but not `
evil.com`.
# Interoperability risk
# Compatibility risk
Shipping this will be a balancing act. Once we're confident that the mechanism works the way I expect it to, we'll need to make sure that impacted developers (like Spotify, Dropbox, GitHub, Google, Pebble, Plex, etc) understand the changes we'll be asking for in their applications.
# Ongoing technical constraints
None.
# Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?
Yes. WebView will be another balancing act, as I'm sure there's significant usage of WebView inside applications that talk to themselves via a local server.
# OWP launch tracking bug
# Requesting approval to ship?
Ha. Ha ha. No.
I plan on moving forward in two broad phases:
1. I'll implement the pieces that can be done purely in Blink with our existing CORS framework. Connections to hosts like `localhost`, `127.0.0.1`, `192.168.0.1`, and `server.local` can be identified a priori as "intranet", and we can trigger the preflight accordingly. This might go pretty quickly.
2. In parallel, I'll work with //net folks to determine the best way to trigger a preflight after socket connection. This will enable us to implement the same behavior for hosts which we can only detect after a bunch of network complexities like `
spotilocal.com` and `*.plex.direct`. This requires design work and refactoring.
Thanks!
-mike