Intent to Implement: CORS restrictions on internet-to-intranet connections.

367 views
Skip to first unread message

Mike West

unread,
Feb 29, 2016, 8:55:18 AM2/29/16
to blink-dev
(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.

** Note that this is an evolution of an earlier, more draconian proposal that would have blocked requests outright. Conversations at https://news.ycombinator.com/item?id=9210484 and https://crbug.com/378566 might give you a feel for the way that was received.

# 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 capability presents substantial risk to users, however. CSRF attacks on routers (and the growing spectrum of IoT devices) (http://malware.dontneedcoffee.com/2015/05/an-exploit-kit-dedicated-to-csrf.html), attacks on poorly written local servers (https://code.google.com/p/google-security-research/issues/detail?id=679https://code.google.com/p/google-security-research/issues/detail?id=693), etc.

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
It's early days. There's been one thread on public-webappsec@ (https://lists.w3.org/Archives/Public/public-webappsec/2016Jan/0000.html), with general interest from some Mozilla folks, and some skepticism from folks who write applications that run on users' local machines.

# 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

# Link to entry on the Chrome Platform Status https://www.chromestatus.com/features/5733828735795200

# 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

PhistucK

unread,
Feb 29, 2016, 9:18:46 AM2/29/16
to Mike West, blink-dev
This means that local servers must use HTTPS, right? This is problematic, if I remember correctly .

A check in Blink will be just a defense in depth (really, a shallow defense) kind of thing, right? The ultimate decision will be of the browser (or the network stack) anyway, right?


PhistucK

--
You received this message because you are subscribed to the Google Groups "Security-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to security-dev...@chromium.org.

Daniel Bratell

unread,
Feb 29, 2016, 9:34:57 AM2/29/16
to blink-dev, Mike West
On Mon, 29 Feb 2016 14:54:50 +0100, Mike West <mk...@chromium.org> wrote:

2. We'll entirely deny non-secure origins on "the internet" the ability to make requests to "the intranet".
...
# Interoperability risk
It's early days. There's been one thread on public-webappsec@ (https://lists.w3.org/Archives/Public/public-webappsec/2016Jan/0000.html), with general interest from some Mozilla folks, and some skepticism from folks who write applications that run on users' local machines.

# 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. 

Presto Opera does not allow connections between the three zones {localhost, private network, internet} and the main problem (that I know about) is captive portals on hotels, airports and other semi-public networks. If you block hard or is very scary, people will use another browser that just works (i.e. a less secure browser than Opera. :-( ).

(Then it was a rather tricky feature to implement with addresses being able to change network type over time so cached information might be incorrect and there are addresses that are network-neutral (data, javascript, about, ....). )

But all in all, I think this is the right thing to do, though I will let someone else comment on details.

/Daniel

--
/* Opera Software, Linköping, Sweden: CET (UTC+1) */

Philip Jägenstedt

unread,
Mar 1, 2016, 8:30:37 AM3/1/16
to Mike West, blink-dev
That 0.5-0.9% sounds crazy high, do you have any clues about the cause of this?

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Mike West

unread,
Mar 2, 2016, 3:20:34 AM3/2/16
to Philip Jägenstedt, blink-dev
On Tue, Mar 1, 2016 at 2:30 PM, Philip Jägenstedt <phi...@opera.com> wrote:
That 0.5-0.9% sounds crazy high, do you have any clues about the cause of this?

I don't. I know of some specific high-traffic examples like Spotify, but I can't imagine that those cover 0.5% of the total page views. The weekday/weekend swing indicates work-related sites, which makes sense, as I'm sure that folks at work tend to visit pages that load in resources from intranet endpoints. *shrug*

In any event, once I have a prototype I can actually point developers to, I plan to do a bit more research and start chatting with folks. For now, I'd like to make sure that we can actually do the things I plan on doing. :)

-mike

Philip Jägenstedt

unread,
Mar 2, 2016, 3:24:28 AM3/2/16
to Mike West, blink-dev
Best of luck, hope it works out! 

roney...@gmail.com

unread,
Jun 13, 2016, 5:51:56 PM6/13/16
to blink-dev
Hello Mike,

Have any schedule idea for the phase 1?

Thanks,
Roney

Mike West

unread,
Jun 14, 2016, 3:52:13 AM6/14/16
to roney...@gmail.com, blink-dev
On Mon, Jun 13, 2016 at 11:51 PM, <roney...@gmail.com> wrote:
Hello Mike,

Have any schedule idea for the phase 1?

I have ~80% of an implementation of phase 1 behind a flag, requiring the preflight and new headers for XHR, Fetch, and Web Sockets. The remaining kinds of resource requests run through `ResourceFetcher`, which doesn't know anything about preflights. It's looking like a pretty substantial amount of refactoring to teach it that concept. It might end up making more sense to skip phase #1 entirely, and move right to the //net stack; that's also a substantial amount of work, but it would solve the whole problem rather than pieces.

One way or the other, I plan to have something that I can put behind the experimental web platform features flag in Q3.

-mike
Reply all
Reply to author
Forward
0 new messages