7

Let's say i have an API at https://mysite/api/getSensitiveData that:

  • Uses GET
  • Protected with cookie authentication
  • Returns JSON with some sensitive data

A bad guy creates a site on his server that has an image tag:

<img src="https://mysite/api/getSensitiveData"><img>

Now browser will execute this request and send the cookie and data will be loaded (as far as I know at least) and then since it's not an image nothing will be shown.

But the request was executed on a site where a bad guy controls javascript. Is there any way that the response can be read from image, some interception of requests or some other method?

P.S. Maybe there are some other similar possibilities, not necessarily img tag?

Ilya Chernomordik
  • 2,197
  • 1
  • 21
  • 36

1 Answers1

8

With just an image tag - no. For the attacker to be able to gather data from the API endpoint and return it to himself, he would have to have javascript on the page under his control. With javascript/ajax requests the browser will still pass along cookies and therefore authenticate his request, potentially allowing him to receive a response and then send it off to a new server.

However, any attempts to do this will run afoul of the same origin policy in the browser. This states that if a script requests a document from a site with a different host, port, or protocol, the response will be denied from the script unless it is explicitly approved by the destination site. The most common way to approve cross-domain requests is via CORS. As a result, the only way an attacker would be able to actually read the response from your endpoint and retrieve the data is if you (the domain owner) have explicitly told CORS to allow credentials and also white-listed the domain name that the malicious javascript is running on.

To get around that restriction the attacker would have to get their own javascript to run on your domain, but at that point in time we're talking about an XSS attack, and you're pretty much hosed. There are ways to prevent data from getting back to an attacker even in the event of a successful XSS attack using well configured CSP headers, but CSP headers can be tricky to get right and they don't yet have broad browser support (in particular IE).

The closest analog to what you are talking about is XSSI/JSON hijacking. These are different techniques to bypass same-origin-policy restrictions in the browser:

http://www.thespanner.co.uk/2011/05/30/json-hijacking/

However, the techniques that allow these restrictions to be circumvented have largely been patched in modern browsers, making the vulnerability much less relevant:

https://stackoverflow.com/q/16289894/1921979

It is always possible that additional such weaknesses can be found in the future, in which case there are some techniques to protect against XSSI (h/t Xavier59):

https://security.stackexchange.com/a/110552/110133

Conor Mancone
  • 29,899
  • 13
  • 91
  • 96
  • Great answer! +1 Minor nitpick: I think the termp SOP should be somewhere in there. – Anders Apr 26 '18 at 19:32
  • 1
    Vulnerabilities allowing JSON hijacking still pop from time to time. There is a good solution here to definetly prevent it : https://security.stackexchange.com/a/110552/110133 – Xavier59 Apr 26 '18 at 19:44
  • So that means that even if you can execute a request to another web server using img/script or some similar tags, there is no way you can read the response? Because CORS does not help against this, only for AJAX requests as far as I know. I suppose that it is actually not possible only because of these security issues. – Ilya Chernomordik Apr 26 '18 at 21:37
  • @Anders SOP as in standard operating procedure? – Conor Mancone Apr 27 '18 at 12:20
  • Sorry about the three letter abbrevation frenzy. :-) Single origin policy. – Anders Apr 27 '18 at 12:21
  • lol! I was reading a bit more about XSSI when I realized that. Duh. Thanks! – Conor Mancone Apr 27 '18 at 12:26
  • @IlyaChernomordik CORS does not stop you from doing something like putting the API endpoint as the `src` attribute on a script tag. In that case the browser will indeed hit the endpoint and try to treat it like javascript. That is pretty much the source of the XSSI attacks that I discuss above. However, even still the attack is not straight-forward, because interpreting a JSON document as javascript doesn't actually leave the attacker with a straight-forward way to see the response. If you read up on the links I provided regarding XSSI that might help. – Conor Mancone Apr 27 '18 at 14:20
  • Well, thanks for the answer! Seems that the design was "insecure first", would be more logical to have CORS by default on all and only allow to execute cross domain if explicitly allowed be it script or not. But I guess there is tons of legacy involved from times when no one cared about security :) – Ilya Chernomordik Apr 27 '18 at 14:22
  • @IlyaChernomordik That really is a lot of it. It would be more secure if cross domain requests weren't even possible unless approved by CORS, but that's not how it works. You can make a cross-domain request to a different site and it will receive the request without problem and potentially take action as a result - the only thing that CORS does is stop the originating script from getting the response back. I think the reason CORS is relatively limited is because it was added late in the game and making it more strict could have broken most of the internet (I exaggerate a little). – Conor Mancone Apr 27 '18 at 14:28
  • I suppose actually it would, all the scripts and image would top loading at once, etc. :) Actually CORS does stop the request if it does the preflight, but it does not always do that, but won't be hard to avoid I suppose. – Ilya Chernomordik Apr 27 '18 at 14:32