Same Origin Policy (SOP) is a key security mechanism within the browser that I’ve written about previously. In short, it prevents applications at different origins from interacting with each other. An origin is defined as the domain name, application protocol, and port number.
If an attacker can bypass any protection implemented around JSONP then they can likely steal confidential information and potentially perform an account takeover, through cross-site request forgery attacks.
As with HTML5 postMessage, origin validation must be performed by the developer. For this an exact match against a whitelist of approved origins should be used, however alternatively a developer may choose to match against a regular expression and several problems be introduced.
For example if a match against any subdomain was desired a developer might check that the origin ends in the allowed domain, aiming to allow domains such as www.example.org and members.example.org to share information. If this is done through a regex such as:
Then an issue arises that the malicious domain must simple end with example.org, there’s no preceding dot enforced before the domain example.org and so the following domain matches and could be used by an attacker:
To avoid this issue a more complex regular expression could be developed such as:
The intention here is that the domains members.example.org, www.example.org and admin.example.org are allowed to communicate. This is enforced through ensuring that one of the three subdomains is at the start of the origin and example.org is at the end. A cursory inspection of this regular expression would show that it looks strict and secure, however the developer has forgotten that with regex a dot character is actually a wildcard not an explicit full stop! Therefore the following domain would also match this expression:
The intended regular expression is only subtly different and would have been the secure choice:
The general recommendation for secure cross-origin would be to utilise features within HTML5 such as CORS and postMessage. Wherever origins must be checked ensure that this is either done as an exact match against a whitelist or origins, or where regular expressions are used ensure that allowed domains are checked along with their preceding dot character and that the dot within domains are “slashed-out” so that they explicitly match only the dot character.