Created attachment 8531084 [details] soppoc.tar.gz User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.101 Safari/537.36 Steps to reproduce: It's possible to bypass SOP via DNS rebinding attack. Exploiting this vulnerability also benefits of the browsers behavior to do new DNS requests for Domains with trailing dots. (example.com <> example.com.). This also works in Chrome, Safari and Opera, I'll also open bugs there. In the attached example (sop.html, comments included in the file), I combine this behavior with a DNS rebind attack. I've setup a PoC demo system demonstrating the issue here: http://sop.vulnerable.wtf user: sop pass: 2e5aW8P9Gn The PoC system reads data served on 127.0.0.1:80 -- so just make sure something is readable there by your browser before giving it a go :) For reproduction of this demo system you'll need: - the attached dnsbind.py script - a webserver serving attached sop.html and index.html (see nginx.conf) - NS records pointing to the server running the Python script - a DNS server which accepts short TTL (126.96.36.199 works fine :) ) - a target / victim webserver which accepts any vhost / has a catchall vhost (that works with home routers just fine) My NS configuration (server_ip=188.8.131.52): ns.vulnerable.wtf. A 184.108.40.206 sop.vulnerable.wtf. A 220.127.116.11 sop.vulnerable.wtf. NS ns.vulnerable.wtf *.sop.vulnerable.wtf. NS ns.vulnerable.wtf In dnsbind.py you'll have to configure the server_ip, server_domain and reply_map according to your needs. As for the spoofed IP, private and public IP ranges are possible. Actual results: To explain the workflow, we assume that the vulnerable domain is example.com with the public IP 18.104.22.168 and we want to grab data from the users home router, which we assume runs on 22.214.171.124, so the workflow is as follows: - User clicks on link to example.com - Browser does DNS lookup and gets 126.96.36.199 - Browser renders page, containing SOP bypass code (sop.html) - A new window is opened via JS, pointing to example.com. , causing the browser to do another DNS lookup - DNS server replies 188.8.131.52 - Browser opens home router page, URL shows example.com. - A request to example.com./foo.jpg is made, to cause another DNS refresh - DNS server replies 184.108.40.206 - Bypass code sets the window.location to "example.com." - Bypass code checks if it's called with trailing dot... if yes, it checks for a window with a predefined handle - Window is found, and actually contains the routers page - Bypass code reads content from the window, which is allowed by SOP, as both Windows got the SOP triple (http, example.com., 80) It does not matter if you use this attack for accessing data on public or private (192.168., 10. etc) IP's, both work fine. Expected results: It shouldn't be possible to violate SOP :) For fixing this issue, I'd suggest: - DNS cache for example.com and example.com. (trailing dot) should be kept synchronous - (maybe) Disallow / Warn user about a domain that changes it's IP between page navigation/window opening - Do SOP checks against the original source IP of the Tab/Window, not only the domain.
Oops, forgot to mention: I tested that PoC on Firefox 34.0.5 / Windows XP SP3 and Firefox 34.0.5 / Linux (Debian jessie), but that's also written on the demo page. :)
Also confirmed this on Windows 7 64bit with the latest Firefox release, from the nature of the issue, I'd say it's OS independent.
example.com and example.com. MAY NOT be the same domain depending on your local resolver. Unlikely, but possible. The general protection against DNS rebinding is for the _server_ to verify the Host: header when someone connects to it. A server that doesn't is vulnerable to DNS rebinding attacks. There are legitimate cases where sites change their IP from connection to connection (large farms, error roll-over) which makes rebinding protection hard on the client side. This is a known issue (that we don't have a good solution to) so I don't think hiding the bug is helping protect anyone.
While acknowledging this is a problem, I'm going to do the honest thing and wontfix this because The mitigations are 1] for the server to verify the host header 2] for the server to run https and rely on the client enforcing certificates properly More broadly, we've come to the realization that https is necessary to have the level of trust desired here. Those plaintext transactions are subject to an innumerable number of hijacking attacks, including but not limited to their address resolution.