JSONP for cross-site Callbacks
JSONP is an unofficial protocol that allows making cross domain calls by generating script tags in the current document and expecting a result back to calls a specified callback handler.
The client JavaScript code to make a JSONP call looks like this:
function jsonp(url,callback,name, query) { if (url.indexOf("?") > -1) url += "&jsonp=" else url += "?jsonp=" url += name + "&"; if (query) url += encodeURIComponent(query) + "&"; url += new Date().getTime().toString(); // prevent caching var script = document.createElement("script"); script.setAttribute("src",url); script.setAttribute("type","text/javascript"); document.body.appendChild(script); }
The idea is that this code adds a <script> tag dynamically to the page and when this code loads it causes the JavaScript that the server loads to be executed. Because it uses the DOM and a <script> tag this gets around the cross site scripting limitations of the XHR object.
The server is expected to return JSON data, but with a slight twist: It has to prepend the callback function name, which is passed as part of the url. The syntax for a JSONP Url is simply the URL with a jsonp= query string parameter that defines the the callback function:
http://someserver.com/mypage.aspx?jsonp=callbackFunction
If the server wants to return a result like:
{ "x": 10, "y": 15}
the result will be turned into (assuming the callback specified is callbackFunction):
callbackFunction( { "x": 10, "y": 15} )
If you're implementing this in an ASPX.NET page it might look like this:
public partial class JSONP : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!string.IsNullOrEmpty(Request.QueryString["jsonp"]) ) this.JsonPCallback(); } public void JsonPCallback() { string Callback = Request.QueryString["jsonp"]; if (!string.IsNullOrEmpty(Callback)) { // *** Do whatever you need Response.Write(Callback + "( {\"x\":10 , \"y\":100} );"); } Response.End(); } }
The client will now have script tag that gets added to the document and the script executes on load and in effect calls the callbackFunction with the parameter:
function callbackFunction(Result)
{
alert(Result.x + " " + Result.y) ;
}
And there's a cross domain callback.
Note that this callback requires that the server KNOWS it's receiving a JSONP request because the server has to prepend the callback handler name supplied so the code can fire in the client.
Yeah it seems like an Exploit
I'm not sold on the idea, because it is basically exploiting what seems to be a security hole in the browser and one that apparently won't be plugged as many services like Adsense rely on it. But all this talk about preventing cross site scripting are pretty much moot by allowing this sort of hack to work. But then again this implementation doesn't do anything that couldn't be done before or changes any of the security issues - it just takes advantage of this functionality.
Still - it feel... wrong <g>...
It is what it is and it seems this approach is getting more popular in being able to retrieve JSON content from various public sites. It certainly is something that should be useful for ASP.NET developers who internally need to make client callbacks to their own internal sites which seems a frequent request.
The Voices of Reason
# re: JSONP for cross-site Callbacks
To me it seems either we should allow XSS or not but there are already those holes via <script> and <iframe> that it doesn't make a lot of sense to have XHR not support cross site too.
# re: JSONP for cross-site Callbacks
I have railed about this so many times I'm not even going to bother to point to the "places".
If you are going to enforce some sort of "security", it needs to be one that all the browser manufacturers can come together on and implement *Seamlessly* across the board. That means XHR, IFRAME, dynamic script tags, whatever.
There are 2 kinds of people in the world - the casual user - who wants to be "protected" from the bad guys without having to think, and we developers, who love to think.
We lose.
# re: JSONP for cross-site Callbacks
The real question to ask is: What is the behavior that we as developers would want without compromising security? XSS is a real threat, but as long as hacks like this exist limiting XHR to not support cross-domain calls just seem silly.
# re: JSONP for cross-site Callbacks
JSONP just exploits that fact and doesn't IMO at least make this problem any worse.
# re: JSONP for cross-site Callbacks
http://widgets.dotnetkicks.com/
So much so, in fact, that if I wanted to even show you the HTML code behind that page by sending the URL to the file in Subversion (as in http://dotnetkicks.googlecode.com/svn/trunk/Widgets/Web/index.html), it gets served up as a web page and becomes fully functional in the browser, doing XSS between domains dotnetkicks.googlecode.com and www.dotnetkicks.com. So childishly simple that there's almost a devlish and wicked feeling to it that you may recall from childhood. Now, it's just the grown up man in you fighting because now you're saying, "We're not supposed to be having this much fun, are we?" ;)
# re: JSONP for cross-site Callbacks
{ "x": 10; "y": 15} should be { "x": 10, "y": 15} I think..
# re: JSONP for cross-site Callbacks
Shared js As New System.Web.Script.Serialization.JavaScriptSerializer()
js.Serialize(myResponse)
# re: JSONP for cross-site Callbacks
# re: JSONP for cross-site Callbacks
# re: JSONP for cross-site Callbacks
Note:
The 'callback' argument of the javascript 'jsonp' function does not get used, which is a bit confusing since the server has a local variable Callback in its helper.
Looks like the 'query' argument to jsonp function is used, instead, to indicate the javascript callback function on the client that the server would inject its own arguments for...
Your example is still instructive and very appreciated.
# re: JSONP for cross-site Callbacks
I will only be serving my application to one client so I just hard coded the call back function into the part of the service that builds the linq class.
There were several times I thought I was stuck for good but now I'm on a roll. Thanks Rick!
p.s. I had gotten all of the above but this, I wondered why in debug mode I could see my data in a file in studio but it never made it back to the success function. Now I know.
# re: JSONP for cross-site Callbacks
The big wheel keeps on spinning. I would say Linq and prototype are two pretty good things in combination once you get the hang of them.
# re: JSONP for cross-site Callbacks
A "normal" ajax call that uses XMLHttpRequest is quiet. That means the user has no real clue it is even happening.
This method is not. It will show the page as loading in the brower every time you make the call.
This is fine if you are doing it all at the initial page load but quite annoying if you are looking for the Web 2.0 feel.
My $0.02(which is all that's left in my stock portfolio after Obama won).
# re: JSONP for cross-site Callbacks
# re: JSONP for cross-site Callbacks
Look at this bit of your JSONP server code:
Response.Write(Callback + "( {\"x\":10 , \"y\":100} );")What you're doing there is letting an arbitrary user generate a URL that causes your web app to generate a document containing a string of their choosing. If the string they supply looks, instead of like a javascript function name, like a chunk of arbitrary HTML, well you've just created a user-configured webserver. One that serves up arbitrary webpages from within your domain, with access to your domain's cookies. (note, you're not even setting response contenttype to text/javascript, so serving up HTML from the page is trivial)
Unless you validate that the Callback value is a plain JavaScript identifier, you're creating a huge security hole on your server with that line of code.
# re: JSONP for cross-site Callbacks
I hadn't thought about the Cookie issue though - in fact as you say hadn't thought much about the server vulnerability. I suppose HtmlEncoding any user input would also fix that potential problem of generating output that might contain script code.
Thanks for the perspective I'd missed.
# re: JSONP for cross-site Callbacks
Long time reader, first time blogger.
I've been using this XSS issue for a while and it works great. The only problem that I have encountered is that Microsoft Internet Explorer (up through version 7 at least) has a limitation on URI lengths of 2083 (and querystrings of 2048 characters). See http://support.microsoft.com/kb/208427 for details. If your generated URI exceeds this length then IE silently decides not to make the HTTP GET request. Ironically, IIS allows 16,384 characters for an HTTP GET request.
All other major browsers have no such restriction or a much higher limit for URI length. See http://www.boutell.com/newfaq/misc/urllength.html for one research report.
Do you know of a way to do XSS with an HTTP(S) POST or any other way to have XSS work in IE when the data that needs to be sent to the server exceeds IE's URL length limit?
I thought about somehow compressing the querystring but to do so effectively in Javascript under IE kind of scares me.
# re: JSONP for cross-site Callbacks
As far as I understand it- here is the problem scenario:
A hacker could
1) access someone's machine after they have visited the site
2) use telnet or a low-level application to forge a GET request,
3) inject some javascript to display domain cookies before the callback function name.
All of this is done in order to see the cookies from my site's domain. If the hacker already has physical access to the box, can't they just choose view> cookies?
Please correct me if I am mistaking the process or the problem. I need to make sure that this site is secure.
I have done a lot of research today, but I have not seen any evidence of exploitation of sites using JSONP. (Excepting very obvious SQL-Injection against non-validated query-string parameters.)
I don't store anything except the ASP.NET session auth-cookie - which expires quickly. So, based on these assumptions, I don't believe that this vulnerability affects my application.
# re: JSONP for cross-site Callbacks
# re: JSONP for cross-site Callbacks
I having the same problem what parvinder is having.And have no idea how to get it solve.Pls help
pawan
# re: JSONP for cross-site Callbacks
After all, this is web 3.0 stuff , yes 3.0, content should be exchangeable between machines..
# re: JSONP for cross-site Callbacks
# re: JSONP for cross-site Callbacks
The plugin has nice features that are missing from current jQuery's implementation.
# re: JSONP for cross-site Callbacks
My second question is this? is there any thing out on the market or any secret trick that you can set up a boomerang type retaliation. What I mean is sending them back what they are sending me. I am almost 100 percent sure I know where mine is coming from and I just know enough to be dangerous and illegal on what i can do or cant.
oh and a third question ...sorry, but is there any thing that will let me know in the data that it is bad. I run wire shark and I will often view behind a page and read its source data and pick up a lot of what it is trying to do ,.
....but then again who I am dealing with must not be more than a script kiddie or else I would not have a clue they are with me. :)
# re: JSONP for cross-site Callbacks
visit my Blog:Studentacad.com
# re: JSONP for cross-site Callbacks
http://abcoder.com/javascript/jquery/jsonp-first-timer/
# re: JSONP for cross-site Callbacks
This response works also:
Response.Write(Callback + "( {x:10 , y:100} );");
# re: JSONP for cross-site Callbacks
Can anyone explain me in detail how i need to call this from Client Side Code.
I already hosted service on some other domain but i am not able to understand how i need to call the same. So I would appreciate if anyone could send me the whole snippet of HTML & JS code which needs to be used to call the service hosted.
The service URL is (for testing) :
http://210.7.74.218/V1_Ser/JSON.aspx?jsonp=callbackFunction
Please revert back ASAP.
Regards
Surya
# re: JSONP for cross-site Callbacks
So just like XSS, it's up to the app owner to secure their shit.
Saying JSONP is dangerous is retarded.
# re: JSONP for cross-site Callbacks