JSON with padding or JSONP is a method to access JSON data from another web site. This can lead to security vulnerabilities if the JSON data contains sensitive information.

Same origin policy and JSON

JSON is a data format widely used in web applications that uses JavaScript notation to describe objects and values. By default, the same origin policy prevents reading JSON cross site. That is, the site https://attacker.com/ can not read https://my.webapp/data.json. There are two common ways to enable that, so that the data can be read cross-site:

How JSONP works

JSONP is a little bit of a hack. It wraps the data in a function call. If you have this JSON:

{"hello": "world"}

JSONP will call some function with this data:

somefunction({"hello": "world"})

So the padding here is somefunction(...) and the original JSON is passed into it. This makes it possible to read the JSON cross-site, by including the JSONP resource as a script:

<script src="https://my.webapp/data.jsonp">

This will call somefunction with the data, and this data can be used by providing a function with that name:

<script>
  function somefunction(data) {
    // The data variable will contain the JSON data.
  }
</script>
<script src="https://my.webapp/data.jsonp">

Security risk

JSONP makes it possible to access data from another website. This makes it possible to retrieve personal data from a logged-in user. If the data is specific to the user, or can only be accessed by an authenticated user, other sites should not have access to it. However, JSONP makes it possible to retrieve the data in a CSRF-style attack.

The attacker’s site includes the JSONP URL as a script. The browser performs the request, and sends cookies along if the user is authenticated. The JSONP will return the data for the authenticated user, and the attacker’s site can read that. The attacker’s site uses the current session of the user to perform an authenticated request.

Callback parameter

The “padding” or function to call with the JSON data, is often specified as a parameter. Often this parameter is called callback and is reflected as-is in the response.

Checking for JSONP

You can recognize JSONP by the parameter in the URL or the POST data that is then used as function call.

Sometimes, JSONP is not used by the site but the API still supports it. To check an endpoint for JSONP support, try this:

  • Add a callback parameter to a JSON URL, by appending ?callback=something to the URL.
  • When a format type is provided, change it to JSONP. Change ?format=json to ?format=jsonp.

Try it: see if you can obtain the data from this URL from a script running on another domain.

Conclusion

JSONP can be a serious security vulnerability. When testing JSON endpoints it is worth a try to look if they support JSONP.