30

Why do browsers apply the same origin policy to XMLHttpRequest? It's really inconvenient for developers, but it appears it does little in actually stopping hackers. There are workarounds, they can still include javascript from outside sources (the power behind JSONP).

It seems like an outdated "feature" in a web that's largely interlinked.

Bart van Heukelom
  • 43,244
  • 59
  • 186
  • 301

1 Answers1

24

Because an XMLHttpRequest passes the user's authentication tokens. If the user were logged onto example.com with basic auth or some cookies, then visited attacker.com, the latter site could create an XMLHttpRequest to example.com with full authorisation for that user and read any private page that the user could (then forward it back to the attacker).

Because putting secret tokens in webapp pages is the way to stop simple Cross-Site-Request-Forgery attacks, this means attacker.com could take any on-page actions the user could at example.com without any consent or interaction from them. Global XMLHttpRequest is global cross-site-scripting.

(Even if you had a version of XMLHttpRequest that didn't pass authentication, there are still problems. For example an attacker could make requests out to other non-public machines on your intranet and read any files it can download from them which may not be meant for public consumption. <script> tags already suffer from a limited form of this kind of vulnerability, but the fully-readable responses of XMLHttpRequest would leak all kinds of files instead of a few unfortunately-crafted ones that can parse as JavaScript.)

bobince
  • 528,062
  • 107
  • 651
  • 834
  • 1
    The first is easy to fix, just don't send basic auth and cookie info with requests to other domains. Can't the intranet problem be solved by checking the referer header server-side, or doesn't XHR send that? – Bart van Heukelom Dec 02 '09 at 02:38
  • 2
    Referrer checking is not a security mechanism and should never be used for anything but leech-prevention. In any case some implementations have allowed the `Referer` header to be set to anything by the script (along with many other arbitrary headers). – bobince Dec 02 '09 at 02:47
  • 1
    But it is here. If browsers would always send the referer header and the server checks for it, an XSS attack is impossible. I'm talking about an ideal future here, so there would be no iplementations where the referer header can be removed. – Bart van Heukelom Dec 02 '09 at 02:56
  • 2
    The Referer header is often blocked or simply not forwarded by proxies. You would also need to `Vary: Referer`, which makes caches unhappy. It should not be relied upon today and certainly should not be used to build to build new security systems on top of. – bobince Dec 02 '09 at 16:59
  • 1
    Then use a new header, "X-XHR-ClientHost" or whatever – Bart van Heukelom Dec 03 '09 at 13:19
  • 4
    It's called ‘Origin’. It, and related standards to allow safe cross-site requests are in preparation, but it's going to be a long time before it's all standardised and ready for use. See http://www.w3.org/TR/XMLHttpRequest2/ for work in this area. – bobince Dec 03 '09 at 15:22
  • 1
    Might be very soon, if you look at how browsers these days quickly adopt technlogies still in draft status. – Bart van Heukelom Dec 05 '09 at 00:12
  • 1
    @bobince, Yes `Origin`. Exactly. What's wrong with using `Origin` checks to prevent unauthorized access? Surely no legit proxies would strip out Origin headers right? – Pacerier Mar 29 '15 at 01:27
  • For me this is made the other way around. It should be the client the one that doesn't share authentication tokens with attacker.com, or the one that has to explicitly agree to share them. Not example.com having to accept or deny other domains. Strange mind the one who came to the current solution – user1156544 Nov 16 '16 at 16:36