Main Content

Heya - HollyGraceful here, I make all of this content in my spare time, like it? Please support me :)
You can donate via Bitcoin or Patreon!

JSONP Vulnerabilities

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.

There are now features in HTML5 that allow cross origin communication called Cross Origin Resource Sharing and Cross Domain Messaging (postMessage) which addresses the possible business need for cross origin sharing, however before this a workaround was developed called JavaScript Serialised Object Notation with Padding (JSONP).

JSONP is a workaround to allow communication between origins, by smuggling the data within JavaScript, and utilising a callback to move the data between origins. It’s convinient and served a potentialy business purpose, although it has no built in security and this has to be manually enforced by the developer, which is where possible security issues occur.

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:

^.*example.org$

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:

fooexample.org

To avoid this issue a more complex regular expression could be developed such as:

^(members|www|admin).example.org$

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:

wwwxexample.org

The intended regular expression is only subtly different and would have been the secure choice:

^(members|www|admin).example.org$

 

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.