In our web application we have run into the situation where we need to do a cross-domain AJAX calls from one domain we fully control to another domain we fully control. I've been surfing around for the best solution and the two that come to mind are a local file proxy (local file using php::fopen) or jquery/JSONP.
When I look up online I see people routinely talk about how it is dangerous to use JSONP because someone could inject malicious data with it. The dilemma is that most of the arguments against it do not seem to hold much water so I'm coming here to ask the Stack for clarification.
What are the specific vectors of attack which would be opened up by cross domain JSONP?
From my understanding the only vector for JSONP is the exact same vector which is opened up by including a <script>
tag on your site whose src is to any site that is not controlled by you: That they could turn malicious and start farming user sessions/cookies/data. If that is true, then it would seem that it is not the protocol (JSONP) that is the concern, but rather the source that the data is gathered from.
Because whether it was a server-side proxy, a <script>
tag, or ajax/JSONP the risk is that I'm putting someone else's content on my page, and they could start farming user sessions if they felt obliged (in a way that's exactly what Google analytics does by way of a script tag).
Many vectors that I hear online hinge upon improper validation of user submitted forms and data. In example, JSONP is used to pull some file, which puts data in a form, and then the form is submitted for database insertion. If the data from that form is trusted, because it's from believed-to-be-secure source (JSONP data), and put in without validation, then again it's not the JSONP at fault, but rather improperly validated user input. A user could make the exact same modifications to that form using Firebug, but last I checked no one is calling Firebug a security vector.
The last element is the notion that with the server-side proxy there is a greater ability to filter the results prior to passing it to the client. Yet, whether it is PHP, or Javascript I could filter the results to remove things like , onclick or iframe. Sure, someone client side could alter my javascript function to remove the filtering, but the filtering would only affect their specific client experience, and would not be altered for other users, thus preventing a permanent multi-client XSS attack.
Obviously, there are some benefits to the server side proxy because it would make things like logging potential XSS attacks easier, but in terms of preventing the attack itself both PHP and Javascript seem to have adequate utilities. In some ways, it would seem JSONP is actually more secure than a simple <script>
tag because at least with JSONP the result passes through a function which means it somewhat filtered, rather than just blanket trust, as occurs with <script>
.
Is there some risk that I am missing or overlooking? If I understand the problem correctly, then there is no security risk for in using JSONP to include contents of a file we trust from a source we trust. Is that an accurate assessment?
SOLUTION
If both ends are trusted, there is no danger in JSONP (it's basically just a <script>
tag).
Both Script/JSONP hold the same security vulnerabilities because they are automatically executed, rather than simply transmitting as data. Using a server-side proxy means that the cross-domain return is passed as data and can be filtered for malicious content. If the cross-domain is fully trusted, then JSONP/SCRIPT is safe, if there is any suspicion of risk then pass it through a filter proxy.
There is a BIG difference between server-side-proxy
and <script>/JSONP
. In the first case, you download data, in the latter you download and automatically execute code
When you build a server-side-proxy, the javascript code can use XmlHttpRequest
to download data. This data will not execute automatically; you have to explicitly do something stupid, like eval()
, to get it to execute. Even if the data format is JSON and the other server has been compromised and your own server-side-proxy doesn't catch the compromise, you still have a line of defense available your client code. You can, for example, parse the JSON using a safe JSON parser, and reject malicious script.
But when you use JSONP or a <script>
tag, you are directly including someone else's code. Because its code (and not data), the browser automatically executes it, without giving you a chance to inspect or modify it.
To summarize, server-side-proxy gives you two additional lines of defence -
When you control both ends of the request, most of the traditional security worries about JSONP aren't an issue.
One additional problem that you'll encounter is that some users block third-party scripts as a security measure. That will block your JSONP requests as well. The server-side proxy approach does not have that issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With