Skip to content

Instantly share code, notes, and snippets.

@tmcw
Created August 15, 2013 20:27
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tmcw/6244497 to your computer and use it in GitHub Desktop.
Save tmcw/6244497 to your computer and use it in GitHub Desktop.
Why JSONP is a terrible idea and I will never use it again

Moral Concerns

JSONP is not actually JSON with padding, it's Javascript code that's executed. JSON is not a real subset of Javascript and the way it is not is important to us: via UTFGrid, we are all UTF-8 masters.

JSONP is not safe: it's Javascript that's executed. It's trivial to XSS with JSONP, because JSONP is XSS. Just have a call like mapbox.load('foo.tilejson', …) and if foo.tilejson gets replaced with destroyYoursite(), it gets run. Compare to JSON.parse, which is, on purpose, not eval.

Practical Concerns

JSONP is questionable in terms of performance. To be fast, you want to have the same callback all the time so that you can cache the response. But this leads to a page like

<script>grid('a');</script>
<script>grid('c');</script>
<script>grid('b');</script>

In which the grid function is called by several relatively-anonymous script tags in quick succession. The events browsers give us for script loading suck: the load event isn't the 'evaled and executed' event, it's just the load event. That sucks.

The less performant way to do things is with dynamic callbacks, like foo.php?callback=foobar123213. So every response needs a new request and your cache sucks.

CORS

The future is CORS but it isn't the present: it isn't supported on IE<10. So, we're jfdi'ing it: which means XDomainRequest. Which sucks.

IE sucks, but you choose your kind of suck: the restrictions of XDomainRequest - only the GET HTTP verb, no headers, etc - shouldn't matter to us.

One thing: unlike JSONP, where HTTPS throws a warning but can work, XDomainRequest totally falls flat on HTTP->HTTPS or vice-versa.

What the World Really Needs is an Ajax Library Written By Me

CORSLITE

@tmcw
Copy link
Author

tmcw commented Jul 8, 2014

@47ronin
Copy link

47ronin commented Nov 28, 2016

Are most AngularJS $http.jsonp() projects vulnerable, to some extent?

@aligajani
Copy link

I think so

@crazytonyi
Copy link

CORS isn't really the answer, I don't think. Because it's just a check on the remote server to see how they feel about their resource being retrieved from another site. If my intention is to use ajax to get the browser to download some crazy evil shit from a remote URL, I'm going to make sure that the remote site has Access-Control-Allow-Origin: * set.

@danielpaull
Copy link

So long as you don't blindly eval() the crazy evil shit then you should be just fine.

@ThunderSon
Copy link

They would be vulnerable if calls to sensitive/private info is retrieved from the JSONP call, where data exfiltration could occur by luring users and using XSS to extract the data from that call to your own hosted server (JSONP can be called from anywhere unless referrer is whitelisted server side)

@tomchadwin
Copy link

Any security concern with JSONP if it's on the same site/domain?

@wesleyvicthor
Copy link

say that security breach to google which uses jsonp for gtm.

@Lewiscowles1986
Copy link

Well that Flash trick shouldn't work any more since flash is now disabled in modern browsers.

@StevenLeonCooper
Copy link

This is complete hyperbole in 2022. If your site can be compromised by client-side code then your site already has problems far beyond XSS with JSONP. The worst thing anyone should be able to do with JavaScript is trick your visitors into leaving your website or submitting information to external/different websites. Using JSONP is exactly as dangerous as running a script from a different domain because that's literally what it is. If you couldn't trust a JSONP source, you couldn't trust any type of script you got from that source.

@Lewiscowles1986
Copy link

@StevenLeonCooper you might be surprised to know that other js can have a hash so you know the version you serve to clients is as safe as the code you prior reviewed.

you could instead of JSONP have a web app backend that forwards standard json via a service with CORS rouse turn-key gateways such as CORS anywhere to avoid needing JSONP

@StevenLeonCooper
Copy link

I know how hashing works; my point is simply that JSONP is literally just the same thing as importing a script from somewhere. Plenty of people aren't hash-checking their scripts anyway. JSONP might not be necessary in 2022 but the scenarios in which you would find yourself using it largely mitigate security concerns; otherwise you shouldn't be using it in the first place. I have only needed it recently for 2 properties that I have complete control over but happen to be on different web hosts. It's just an RSS feed of publicly-available data so why would I bother changing my code for no real performance or security gain?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment