New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 11 users

Issue metadata

Status: Fixed
Closed: Aug 2016
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 1
Type: Bug-Security

Blocked on:
issue 624462

Sign in to add a comment

Issue 600352: Security: Cross-Protocol Theft from non-HTTP services via DNS rebinding + HTTP/0.9

Reported by, Apr 4 2016

Issue description


DNS rebinding attacks can be mounted against non-HTTP services to steal their responses cross-protocol. Non-HTTP services' responses can be read via XHR as their response streams will be interpreted by Chrome as `HTTP/0.9`.

This is an issue because, HFPA attacks[0] aside, many services that bind to localhost don't require authentication, and haven't factored browsers being able to read their responses into their threat model. 

For example: MySQL *cannot* be attacked via a standard HFPA attack, as it closes the connection due to the handshake failing while the browser is still writing the HTTP headers; however, being able to read the server's half of the handshake tells us a lot about the server itself[1]. 

Memcached *can* have its contents manipulated via a standard HFPA attack, but this behaviour allows actually leaking the database as well.

Likely all services not bound to blacklisted ports that have "fault tolerant" parsers, or that leak sensitive data before or during the handshake are vulnerable.


Chrome Version: 49.0.2623.110 (64-bit) stable
Operating System: Ubuntu 15.10 as well as OS X / Windows 10


* To simulate a non-HTTP service bound to the loopback run `python -c 'print("\x00\x01I am not an HTTP response\r\n\r\nfoo\x00")' | nc -l 11212` on the same machine as your browser
* Start up a webserver on another host on port `11212` and have it serve the following document:

		<pre id="output"></pre>
		var outputElem = document.getElementById("output");
		outputElem.textContent = "Waiting 120s to fetch";
		setTimeout(function() {
		  var xhr = new XMLHttpRequest();"GET", "http://" + + "/?a=" + (new Date()).getTime());
		  xhr.onload = function() {
			outputElem.textContent = xhr.responseText;
		}, 120000);

* Create an entry for "" in your `/etc/hosts` file that points to the host running your webserver
* Load "" in your browser
* To simulate DNS rebinding, edit the "" entry in your `/etc/hosts` file and make it point to ``
* After 120 seconds the `<pre>` should contain `\x00\x01I am not an HTTP response\r\n\r\nfoo\x00`.

A hosted version of this PoC that uses a custom DNS server[2] to swap the records after the first resolution is at <http://(unique_string)>.

I've also made PoCs that abuse this behaviour to dump local Memcached[3] and Redis[4] databases, as well as the MySQL[5] server handshake. Screenshots for all of these are attached.

Note that this rebinding method requires waiting longer than 60 seconds so the entry in Chrome's resolver cache gets evicted, but a more efficient method may exist. I didn't spend much time on that.


Mitigations for DNS rebinding attacks on HTTP services are well understood, the server forcing the use of HTTPS or verifying the `Host` header[6] in the request mitigates the worst issues. What's less clear is how non-HTTP services bound to non-blacklisted[7] ports should protect themselves.

Previous attacks on non-HTTP services via DNS rebinding relied on now-fixed vulnerabilities in plugins and their TCP socket APIs[8]. This is still an issue due to browsers interpreting anything that doesn't specifically declare itself as HTTP to be `HTTP/0.9`.

I think the best thing would be for DNS servers to filter responses containing "private" addresses, including loopback addresses; however, these filters are not commonly enabled, and are generally insufficient. Many that I've audited do not block loopback addresses, ignore IPv6 or improperly handle its edge cases, etc.

With that in mind, I think the *most reasonable* place to mitigate DNS rebinding attacks on non-HTTP services is in the browser. Since updating the port blacklist for every new service that comes out isn't feasible, we should instead restrict where `HTTP/0.9` is allowed.

The easiest fix would be to disallow HTTP/0.9 on "unusual" ports. If that was too restrictive, we could disallow HTTP/0.9 only if the request was for a subresource or subdocument over an "unusual" port. Loading `HTTP/0.9` at the top level should still be safe.

I'd be interested to hear your thoughts on how this should be mitigated, or whether mitigation is the browser's responsibility at all, as this behaviour is present in multiple browsers and I couldn't find any previous mentions of DNS rebinding + HTTP/0.9 attacks.

412 KB View Download
345 KB View Download
414 KB View Download

Comment 1 by, Apr 4 2016

Components: Internals>Network>DNS Internals>Network>HTTP
Labels: Security_Impact-Stable OS-All Pri-1
+taviso as this may be relevant to your interests
+cbentzel for network triage

Comment 2 by, Apr 5 2016

I just updated my tests and confirmed that <> and friends also repro in Firefox, OS X Safari, and MS Edge. I haven't figured out how to perform rebinding attacks on IE<=11 yet, as its pinning behaviour is even harder to understand than Edge's, but it appears that this issue is pervasive.

Comment 3 by, Apr 5 2016

Labels: Security_Severity-Low Pri-2
Status: Assigned (was: Unconfirmed)
cbentzel, do the proposed fixes in the report look feasible?

Comment 4 by, Apr 5 2016

adding palmer as I think he's chimed in on previous rebinding attacks.

Comment 5 by, Apr 5 2016

Labels: -Pri-2

Comment 6 by, Apr 5 2016

I'd actually love to look at HTTP/0.9 usage and see whether that could be removed. If not restricting it to a whitelist of ports is probably a good mitigation.

Comment 7 by, Apr 5 2016

+mkwst due to internet sites being able to reach intranet/localhost addresses.

Comment 8 by, Apr 5 2016

This now being tracked on Moz's Bugzilla as well, #1262128. I'm waiting until I have more stable repros for Edge and Safari before reporting to them. Since this is a cross-browser issue we should probably coordinate disclosure.

Comment 9 by, May 16 2016

RE #6: Do we have any telemetry on this?

Edge was hesitant to remove HTTP/0.9 support because Chrome had it. Chrome appears to have had it from the original Firefox stack. Firefox supported 0.9 due to buggy servers of the era (e.g. see 

The only *common* occurrence of HTTP/0.9 I'd ever seen were some buggy/misconfigured CDN servers used by Yahoo circa 2006 that would occasionally send images without headers, and these worked fine with IE but blew up Fiddler, so I had to write code to accommodate such responses. Those servers have been long fixed, as I haven’t seen an error like this on the public internet for a long time. The last time I saw a site with this issue was 2014:

Based on all of the browsing I do these days (virtually all of which is through Fiddler) I don’t believe that there’s any public-facing webserver still relying on this support. It’s possible that there’s some legacy device somewhere that was “getting lucky” but it seems low-risk to disable this by default for the browser. But it's entirely possible that there's 0.9 coming from some IoT or other device that's not globally exposed...

Comment 10 by, May 16 2016

#9: I asked mmenke if we had numbers about this - it sounds like there was UMA from before where we would guess that HTTP/0.9 exists but it's not in place any more. I'd be interested in what it would take to get back in as it's possible we could just get by with removing HTTP/0.9

Comment 11 by, May 16 2016

The histogram is still around:  Net.HttpHeaderParserEvent.  ~0.01% of HTTP 0.9/1.x (i.e. not including H2/QUIC) responses are HTTP/0.9 on stable (Closer to 0.02% on canary), and 0.025% of those 0.01% are over HTTPS.  Worth noting that that's how often we interpret the response as HTTP/0.9, not how often it actually is HTTP/0.9.  Responses from broken servers can be interpreted as HTTP/0.9 as long as they don't seem to have an HTTP/1.x status line.

Comment 12 by, May 16 2016

I'd support removing HTTP/0.9.  Its continued existence has bugged me since before I started working for Google, I'd love to see it go.  My only concern is about breaking stuff that depends on it.  Guess we can't really know how bad the fallout will be without just trying it.

Comment 13 by, May 16 2016

Mozilla has some stats on HTTP/0.9 usage in Firefox's beta channel as well:!cumulative=0&end_date=2016-05-12&keys=__none__!__none__!__none__&max_channel_version=beta%252F47&measure=HTTP_09_INFO&min_channel_version=null&product=Firefox&sanitize=1&sort_keys=submissions&start_date=2016-04-25&table=0&trim=1&use_submission_date=0

I feel like Firefox might be interpreting completely empty responses with no status line as HTTP/0.9 to end up with those numbers for sub-resources over non-standard ports, but I'd need to double-check.

Comment 14 by, May 20 2016

Only thing that concerns is me about killing off HTTP/0.9 is about 1% of
users seem to hit this over the course of the week. Per-request basis is
below reasonable threshold. It does seem like it's hard to tell if it's
actual HTTP/0.9 responses or just garbage being interpreted as HTTP/0.9

Comment 15 by, May 20 2016

There are other less aggressive mitigations we could consider.  We could  only allow HTTP/0.9 for main frame requests, or disallow it for cross-site requests, for some definition of cross-site.

Comment 16 by, May 20 2016

I remain convinced that disabling HTTP/0.9 globally is low-risk. 

Unfortunately, DNS rebinding means that a lot of other mitigations we could take (e.g. only allow for main frame requests, disallow for cross-site requests) probably wouldn't help much.

The proposal in the original issue ("disallow HTTP/0.9 on "unusual" ports") does indeed seem likely to be the easiest mitigation if we wanted to maintain support for HTTP/0.9.

Comment 17 by, May 31 2016

Hi Folks, just wanted to give you a heads-up that I intend to publicly disclose this as part of some related inter-protocol exploitation research in 3 months (August 31st.)

If you wish to co-ordinate with the other vendors then the updated bug references are: Mozilla Bugzilla #1262128, Apple ProdSec Followup #639367943, MSRC Case 33254.

Comment 18 by, Jun 1 2016

Thanks for the update, Jordan.

So, Chris:  Should we disable it an hope for the best, or just disable it on unusual ports?

Comment 19 by, Aug 2 2016

This was rediscovered and publicly disclosed at , can probably remove the view restriction.

Comment 20 by, Aug 2 2016

Labels: -Restrict-View-SecurityTeam
Removing the restriction.  Given its low severity classification, and that it's already been publicly disclosed, seem reasonable to open up the bug.

Comment 21 by, Aug 2 2016

Blockedon: 624462
Worth noting that we did indeed decide we'd try to remove HTTP/0.9 support (Which has been removed in M54 - still a ways off from deployment).

Comment 22 by, Aug 8 2016

Labels: M-54
Status: Fixed (was: Assigned)
Assigning to mmenke due to the HTTP/0.9 support.

Should this

Comment 23 by, Sep 1 2016

the POC site from still can get information from a local running redis instance.

55.0.2846.4 canary (64-bit)
OS X 10.11.6

Maybe HTTP/0.9 removing is not enough to prevent this kind of attacks.

Comment 24 by, Sep 1 2016

Follow 624462 for status of the change, which has been landing and reverting as the compat story is nailed down.

Comment 25 by, Sep 3 2016

therealmarv:  Also seems like if a NAT router is using a default login/password, and doesn't have any defense against this sort of thing (Force being accessed by a certain hostname or something), an attacker may also be able to reconfigure your router by similar means, unless I'm missing something.

Comment 26 by, Sep 3 2016

mmenke: Yes, that's the classical DNS rebinding attack. Using HTTPS is the best defense (due to enforced hostname verification) but there are other defenses being explored; see e.g.

Comment 27 by, Oct 1 2016

Project Member
Labels: Restrict-View-SecurityNotify

Comment 28 by, Oct 10 2016

Labels: -M-54 M-55

Comment 29 by, Nov 15 2016

Project Member
Labels: -Restrict-View-SecurityNotify allpublic
This bug has been closed for more than 14 weeks. Removing security view restrictions.

For more details visit - Your friendly Sheriffbot

Comment 30 by, Jul 6 2018

Components: Internals>Network

Comment 31 by, Jul 6 2018

Components: -Internals>Network>HTTP

Sign in to add a comment