Closed Bug 183143 Opened 23 years ago Closed 17 years ago

Setting document.domain doesn't match an implicit parent domain

Categories

(Core :: Security, defect)

defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: koreth-mozilla, Unassigned)

References

()

Details

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.3a) Gecko/20021202 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.3a) Gecko/20021202 Iframes that explicitly set their domain names to a parent domain (e.g. x.foo.com documents that set their domain names to foo.com) can't access parent frames whose sources come from the same parent domain. Reproducible: Always Steps to Reproduce: See the URL, which is a simple test case. It includes three iframes which should all be in the same domain as the parent from the point of view of JavaScript's security model. Actual Results: Documents that are fetched from www.midwinter.com are apparently considered to be in a different domain than documents that explicitly set their domains to 'www.midwinter.com' (even if they came from there in the first place) and the two can't access each other's test functions. A document that came from foo.www.midwinter.com can never access a www.midwinter.com document's test function unless the latter explicitly sets its domain. Expected Results: All three iframes should succeed. They work under Opera 7 and IE 6.
This works for me under Netscape 6.2 and 7.0, I should add, so it's a fairly recent bug.
I believe this was done on purpose to prevent certain security attacks.
Assignee: rogerl → mstoltz
Component: JavaScript Engine → Security: General
QA Contact: pschwartau → bsharma
It's going to break some legitimate apps -- for example anything using a streaming JavaScript service like KnowNow or Kenamea, both of which use frames to communicate with their servers and thus depend on JavaScript's domain security semantics. And the fact that "document.domain = document.domain;" is anything but a no-op seems... well, ugly. Is there a bug describing the security problem this behavior addresses? There must be a way to solve it that doesn't violate the documented security semantics.
> I believe this was done on purpose to prevent certain security attacks See bug 154930 "document.domain abused to access hosts behind firewall"
Status: UNCONFIRMED → NEW
Ever confirmed: true
I also think this was done on purpose. There was a preference which downgrades to the unsafe behavior IIRC.
It does indeed seem to have been done on purpose, but if the comments on bug 154930 are accurate, the preference for turning it off was an interim (1.0-branch-only) thing that wasn't carried forward. I guess I'm stuck decorating all my pages with document.domain=document.domain, even the ones that otherwise don't have a line of JavaScript code. The security provided by this change is irrelevant to me since my HTTP server checks the hostname on incoming requests. Here's a way to get the standards-compliant behavior back for people who need it without requiring a new preference or breaking security in the default case: the HTTP server should return a Host: header line indicating what it thinks its domain is. If present, and it equals the domain of the URL, then the URL's domain should be considered trusted and shouldn't be subject to the new behavior. That should work regardless of load-balancing setups with multiple IP addresses, clients behind proxies with no direct DNS access, etc. And it's better than the current fix at detecting hack attempts: if you get a complete mismatch between the URL domain and the HTTP server's reported name and some JavaScript code attempts to poke around another frame's DOM, it's a pretty good sign something funny is going on.
For Comment #6: Sure this is good idea, but not sure whether it works in the real world. Do you think you can make all web server vendors include Host: tag?
Nope, not all of them, but as long as Apache supports it (which I'm working on) it'll at least be an available solution for people who want standards-compliant behavior from the browser. Not a perfect solution but better than the current situation. Keep in mind that if someone isn't using JavaScript across multiple server hostnames, they can continue using an existing web server with no ill effect; this is only an issue in a small minority of cases and it's only those people who'd have to worry about the server tweak.
The suggestion in comment 6 sounds good, since we don't want to remove this restriction right now. Darin, what do you think?
Status: NEW → ASSIGNED
hmm... servers can certainly exist under multiple domains. we have that here at netscape with host.netscape.com and host.mcom.com being the same. essentially, it means servers would have to look at the Host header passed by the User-agent to determine whether or not it matches one of the Host headers it recognizes, and then it would have to respond with an equivalent Host header. not all at standard, and getting it standardized might be painful given that HTTP folks probably don't want to have to care about JavaScript security ;-) so, are IE and Opera vulnerable to something like bug 154930 then?
Does the attack in bug 154930 differ significantly from the one in bug 149943? I believe they can both be blocked by either (1) at the firewall, disallow external hostnames from resolving to internal IPs or (2) at the web server, disallow requests with bogus hostname headers. So fixing one and wontfixing the other based only on those malicious-DNS-server attacks seems odd. On the other hand, requiring explicit setting of document.domain does help with another case. I believe I am allowed to include scripts on http://jesserud.livejournal.com/, but that doesn't mean I should be able to access stuff on http://livejournal.com/. (Luckily, http://livejournal.com/ redirects to http://www.livejournal.com/.) Seen this way, the only reason "document.domain = document.domain" has an effect is that the meanings for various document.domain strings were chosen poorly. If the initial value for document.domain were "", or if the string for permissive use was required to have a leading ".", we wouldn't be in this strange situation where "document.domain = document.domain" has an effect.
Assignee: security-bugs → dveditz
Status: ASSIGNED → NEW
QA Contact: bsharma → toolkit
What do other browsers do nowadays?
OS: Windows 2000 → All
Hardware: PC → All
(In reply to comment #11) > I believe they can both be blocked by either > (1) at the firewall, disallow > external hostnames from resolving to internal IPs or not everyone has a firewall. and are internal ips the whole problem? >(2) at the web server, > disallow requests with bogus hostname headers. So fixing one and wontfixing > the other based only on those malicious-DNS-server attacks seems odd. > pushing the responsibility to the web server doesn't seem very doable. imho document.domain is on the edge of design flaw.
(In reply to comment #11) > (1) at the firewall, disallow > external hostnames from resolving to internal IPs not sure if this is easily doable and strongly doubt the corporation will make an official statement to all the admins: hey admins, for safer browser experience do some more work and apply additional firewall rules :)
Georgi, those are exactly the same steps corporate firewalls (or web servers behind such firewalls) have to take to protect themselves against attacks like those described in bug 149943. So it's not a good argument against implicit document.domain. I think comment 11 paragraph 2 *is* a good argument against implicit document.domain, though.
(In reply to comment #15) > Georgi, those are exactly the same steps corporate firewalls (or web servers > behind such firewalls) have to take to protect themselves against attacks like > those described in bug 149943. So it's not a good argument against implicit > document.domain. > some questions: 1. iptables based firewall/router and an internal network. what iptables rules should be added? does this involve looking in the dns protocol? 2. no firewall, just http/socks proxy. this is not uncommon. 3. one enters a VPN. the VPN is kind of "internal". so what steps? > I think comment 11 paragraph 2 *is* a good argument against implicit > document.domain, though. > can't find the specifications of legitimate use of document.domain at the moment. are there official legitimate uses of document.domain?
I'm not familiar enough with iptables, socks, or VPN to answer your questions about them. a.foo.com and b.foo.com can both set document.domain to "foo.com" in order to access each other. I don't know how common this is.
(In reply to comment #17) > I'm not familiar enough with iptables, socks, or VPN to answer your questions > about them. > my network knowledge is limited, but i suspect a proper network solution for document.domain will be difficult (not to mention enforcing it). a network expert comment on this? > a.foo.com and b.foo.com can both set document.domain to "foo.com" in order to > access each other. I don't know how common this is. > the situation seems complex.
Setting document.domain to the parent domain is extremely common. If you've used Slashdot, say, you've used a site that uses parent-domain cookies. That's why you stay logged in as you navigate between science.slashdot.org and yro.slashdot.org. IMO the best way to fix this is what I described in comment #6: the server should identify itself in its responses, so there's no possibility of an attacker with a bogus DNS server returning an internal server's IP address to get the browser to fetch a non-public document, which is the attack that prompted the change here. This change can be introduced incrementally, and in a completely backward-compatible way; if the extra header line isn't present in the server's response, the current behavior is the default, but if the header is there, then we trust the URL. If Firefox were to implement that, you can bet all the major Web servers would support it in short order. (Well, maybe except for IIS.)
It is not necessary to set document.domain in order to use domain cookies.
> the server should identify itself in its responses What would that accomplish that the Host header in requests does not? (Btw, it's a violation of the HTTP spec to ignore the Host header.)
As I understand it, the security hole in question is that a malicious outsider can set up a DNS server that resolves a foreign domain name to a private IP address (e.g. 10.x.x.x). If they manage to hit the address of an intranet Web server, then it would be possible to use an iframe in the user's browser to fetch confidential documents from the intranet server, then submit them back to the attacker's web server. For example, the user goes to www.foo.com, which spits out a page that has an iframe pointing to hidden.foo.com and sets its document.domain to foo.com; hidden.foo.com resolves to a 10.x.x.x address, and since the browser would think the iframe came from the same domain that served the outer page, it would let JavaScript code on the outer page examine the contents of the iframe, possibly submitting it back to the attacker's site. The current fix prevents that by treating the iframe as if it came from a separate domain, so the outer page's JavaScript can't get at it by default. (Unless it happens to do the document.domain=document.domain thing.) Having the server identify itself would work because the intranet server would not claim to be foo.com; it would claim to be intranet.company.com or whatever, and the browser would thus know that it should block the outer page from doing anything nasty. As for ignoring the Host header, there are more than a few sites out there whose servers are configured to do just that. Apache doesn't pay attention to it unless you've set up name-based virtual hosts, for example. Most intranet web servers are, I suspect, not hosting a lot of different sites from a single IP address so they're likely set up with a single configuration for all port 80 traffic.
> As for ignoring the Host header, there are more than a few sites out there > whose servers are configured to do just that. So tell the Apache folks their software has a security hole. It would be silly to ask them to implement a new feature to work around it; the new feature requires exactly the same configuration information. Especially since that new feature would waste bandwidth and wouldn't be supported by today's web browsers. As I said in comment 11, the "evil DNS server" attack is no longer the reason why document.domain is not implicit. Web browsers don't even try to protect the simple same-origin case from evil DNS servers; see bug 149943. Discussion of that attack is off-topic for this bug.
Is there any other work around this problem? We have some child windows loading from the same domain, and some from the sub domains. This is a very common practice. For example all dialogs do share the same domain (yyy.com), but ads on the other hand do come from sub domains (ad.yyy.com), and all this loading logic is dynamic. When I promote the child window from our sub domains to talk to parent, I have to set document.domain = document.domain in the parent. The problem with this it brakes the communications with child windows that come from the same domain. Then I have modify all of them, even they are the same domain as the parent. Setting document.domain = document.domain in every page is not a very clean solution code wise imho. I would appreciate if you can find a solution to this problem, that is effecting many developers.
Nobody is happy with document.domain, browser vendors least of all. It was an ill-considered hack from early in web history, and given its problems if we could make it go away entirely I think we would. The solution, supported by the most recent versions of all major browsers, is HTML 5's postMessage(). For older browsers you could do AJAX-y things like JSON. In other words a message-passing system rather than creating a bypass for the same-origin policy.
Assignee: dveditz → nobody
Status: NEW → RESOLVED
Closed: 17 years ago
Resolution: --- → WONTFIX
Blocks: 495176
You need to log in before you can comment on or make changes to this bug.