Hacker News new | ask | show | jobs
by geofft 3076 days ago
Yes.

They can't send arbitrary traffic, though; they can only send valid HTTP requests, and they don't get access to your cookies (because the hostname doesn't match), so the "only" thing they can do is get access to things that an unauthenticated HTTP client running as you could get access to.

This has been true since almost the first web browsers - XHR wasn't a thing, but you could send GET requests with <img src="http://192.168.0.1/reboot-everything"> or even POST requests with forms (a little easier once JS let you create and submit forms from JS, but certainly doable in pure HTML).

And the problem is there's no way to tell what IP addresses to block. Special-casing 127.0.0.1 is at least a clear enough solution to articulate (though it breaks all sorts of use cases where HTTP to localhost on a custom domain name is intended), but should you also block all the RFC 1918 space? Doesn't that break the vast majorities of companies that have internal websites named wiki.example.com or wiki.corp.example.com? And some companies don't even use RFC 1918 space, they use public IPv4 ranges they own for internal routing.

It gets worse - the other problem here is that IP-based access to resources on the public internet is also vulnerable. If you're at, say, a university which has IP-based access to some journals, any website can send HTTP requests to those journals from the university.

The real right solution here is to avoid IP-based access controls, either on the public internet or on your private network - preferably by not having a private network or at least not trusting it, BeyondCorp style. Every HTTP request that does stuff on your behalf needs to be explicitly authenticated, even if it comes from the private network.

1 comments

This makes sense, thanks for the explanation. The unfortunate thing is that setting up a local HTTP server is easy, while proper authentication takes more work. Based on the nature of their fix, it seems Blizzard doesn't really want to expend effort on proper authentication. I wonder if browsers could send a special HTTP header indicating the host that initiated the request?
Browsers (and most other HTTP clients) already send the Host: header, and that appears to be a pretty good way to mitigate DNS rebinidng attacks. It does not save you from things like <img src> attacks.

One common use of local HTTP servers is with the express intent of hosting web pages (not just an API endpoint) that's rendered in an embedded web browser widget, or perhaps even in a real web browser, because the web is a pretty good way of showing UIs. A common example is CUPS - if you're on macOS or most desktop Linuxes, http://localhost:631 is likely to bring up the CUPS admin interface. So browsers saying "I'm a browser" is not really the (un)authorization you want - many times you want browsers, or embedded widgets made from browser code, to access them. So if the Host header isn't enough, there isn't really a better answer than proper authentication. (CUPS is pretty hardened now, but one good solution for CUPS would be a command-line utility that generated a session key and printed out a URL like http://localhost:631/?auth=a1b2c3d4.)

I know about the Host header, my thought was more about something like a Redirected-From header which would be set based on things like the host the <img src> or XHR came from. A simple sanity check on that (anything other than localhost is blocked) should suffice.