October 5, 2009 - 17:36 UTC - Tags: security xss jsonp
Using JSONp imposes some risk on your system, whether you are a providing data or using data published as JSONp.
I'm providing data throug JSONp - What's the risk?As long as you are only providing public data, the most significant risk is injection through parameters. As an example an attacker could perform a SQL injection attack against your JSONp service by manipulating the parameters to the service (if it has any).
If you are providing data that requires authentication, things get much worse. A legit site sets up a callback, includes the (dynamic) script tag to the JSON service, which - upon loading - invokes the callback, and displays the data to the user. What's stopping an attacker from setting up a webpage that defines the same callback and script tag, but instead steals the users data? This is referred to as JSON-hijacking and it's basically a
Cross site request forgery (XSRF/CSRF)-attack.
Several solutions have been suggested around the web. One suggestion is to include a small piece of javascript in the JSONp result, that - before invoking the callback - checks that the domain is a legit site. To use this method, you would have to maintain a list of legit sites.
Another slightly similar approach I've seen, is to have a per user secret that is included as a part of the function name of the callback. The per user secret would have to be known by both the data provider and the data consumer. This secret would preferably have to change from time to time, to mitigate the risk of the secret being known to attackers.
I'm using data provided through JSONp - What's the risk?When you are using JSONp, you are usually including a script from a remote server in another domain. This script can do anything other javascripts can do - like manipulating the page contents, stealing data etc. It's not limited to delivering JSON data. So when you are adding a script tag to another server, you are allowing
Cross Site Scripting (XSS) from that server. You are allowing circumvention of the
Same origin policy - a very important security restriction in the browser.
By adding script tags to other servers, you are exposing your page not only to attacks directly targeted at your website, but also indirect attacks performed by hacking the provider of that script. It's all a matter of trust. Do you trust the provider not to be hacked? Do you trust the provider not to do evil? Unless you can answer yes to both these questions, you shouldn't add script tags to the provider. And that's true for statistics scripts using javascvript as well.
If you want to protect yourself, you could pull the data through a proxying service on your own server. As a part of the proxying, you could validate the data to make sure it's JSON only. This does however have the drawback of not being able to use authenticated data (which usually requires authentication cookies), and it might impose extra stress on your server.