Using JSONP Safely
<script src="https://anywhere.com/data.jsonp"></script> tags are allowed to load files from any domain. This differs from normal AJAX requests, which are only allowed to make requests to the same domain as the page you are viewing.
Unfortunately, many guides to implementing this technique in PHP contain a dangerous security flaw. Can you spot it?
Here is the problem code:
echo $_GET['callback'] . '(' . $jsonData . ');';
This is a textbook cross-site scripting (XSS) vulnerability. Because the value of
$_GET['callback'] isn't sanitized, any arbitrary code can be injected via the URL. Combined with an incorrect Content-Type header, the response will be interpreted as
text/html and executed by your browser.
The right way
Here's how to avoid this flaw:
If you're using Drupal, and the callback value is expected to be unique (as it is with jQuery.ajax()), you may also want to set
$GLOBALS['conf']['cache'] = CACHE_DISABLED. This will prevent the page cache from filling up with one-time responses.
Other security considerations
JSONP has some other limitations, too: It can only be used for GET requests, and there's no general way to prevent cross-site request forgeries*. It's bad for private data, since any site on the web could hijack a JSONP response if the URL is known. This means it's best suited for consumption of public data feeds.
Soon (translation: as soon as IE catches up to the rest of the web) we'll have broad support for Cross-Origin Resource Sharing, and we can let JSONP die quietly.
*You might at first think unique XSRF tokens or doubly-submitted cookies would still work, but the token would have to be retrieved via another JSONP request which could itself be forged. In some narrow cases you may be able to limit (though not entirely prevent!) forgeries by checking the HTTP Referer header.