Same-Origin Policy is a protection mechanism built in to web browsers to prevent malicious web sites from interacting with web sites we visit. I’ve already written a full explanation of the mechanism here, but the TL;DR is that it allows web origins to make requests to other origins but prevents them from reading the response.
Sometimes, however, we may have a business need to allow two origins that we control to interact with each other. One method to allow communication is HTML5 postMessage which I’ve talked about already, another is Cross Origin Resource Sharing (CORS) and I’ll talk about the security implications of CORS here!
So by default SOP won’t allow bi-directional communications between two separate origins, however as applications scale up there may be a requirement to allow this kind of thing. Think of companies such as Google, who also owns YouTube – or Microsoft who also owns Outlook and Skype. They may well want inter-origin communications.
HTML5 CORS essentially allows a developer to set up an access control list to allow other domains to access resources. This can be controlled through the following headers:
Access-Control-Allow-Origin Access-Control-Allow-Credentials Access-Control-Allow-Methods
The concern, if the CORS is incorrectly configured, is that a malicious website could steal confidential information from a vulnerable site – or even execute protected functions. For example if a site is protected through CSRF tokens a vulnerable CORS set up could allow an attacker to steal a valid token and therefore create a valid request.
The first header then is Access-Control-Allow-Origin which defines which sites can interact with, the header can be either a list of origins or a wildcard (*). The second header defines whether or not the browser will send cookies with the request. Cookies will only be sent if the allow-credentials header is set to true and the alow-origin is not sent to a *.
However a vulnerability can still exist if the target web-server reads the “Origin” header from the request and embeds it in the response. The way this could look in the real world is that the the target server could have a list of sites which it is configured to allow CORS with and when a request comes in it reads the origin header, validates it against the list and if the validation returns true the site is embedded within the Allow-origin header.
This sounds fine, from a security point of view, but it’s reliant upon an effective validation of the requesting origin, if there are any issues that could allow that validation to be bypassed then a HTML5 CORS vulnerability occurs.
There are many ways that this validation could be vulnerable, the simplest is that all sites are permitted in this way – either by mistake or for testing purposes.
Another simple example would be where the validation simply checks the existence of a string within the domain, so allowedsite.com is supported to be allowed however allowedsite.com.maliciuos.net could be used as a validation bypass.
A more complex example of a vulnerable validation that we’ve seen in the real world is the check the request origin against a regular expression for the allowed sites line where the developer has included sites such as: “www.allowedsite.com” but forgetten that within regular expressions full-stops (.) are wildcards.
The developer should have ‘slashed-out’ the dot characters so that it reads “www.allowedsite.co.uk” else an attacker could register a site such as “wwwxsallowedsite.co.uk” which would pass the validation and allow the malicious site to perform CORS.
The specifics vary but if an attacker can get their domain into the allow-origin header and the allow-credentials header is set to true the malicious site has essentially the same level of access as the victim user, which could lead to the malicious execution of functions and confidential data theft!
From a testing point of view, you can adjust the request to the potentially vulnerable web server. For example if you are targeting www.testserver.com you can send an Origin headers like the below to test for potential issues:
Origin: wwwxtestserver.com Origin: www.testserver.com.malicious.com