This one surprised me - a lot. A reader wrote me this morning about an issue he was having following my tutorial on using cffileupload. He reported that files were being uploaded but the Flash control kept returning a red error result to the end user. I whipped out my copy of Charles, an excellent network tool, and looked at the response. It's then I noticed that the JSON response was prefixed with //. Now - this is to be expected if you enable the "Prefix serialized JSON with" option in your ColdFusion administrator. However - all of ColdFusion's front end Ajax-y widgets are supposed to recognize and account for this. The end result being you enable the feature and don't have to worry about changing widgets like cfgrid, cfwindow, etc, and certainly cffileupload. Unfortunately, it looks like there is a bug (the report is here) and the feature completely breaks cffileupload.
Now here is where things get interesting. If you read the description in the ColdFusion Admin for this feature, it says:
Protects web services which return JSON data from cross-site scripting attacks by prefixing serialized JSON strings with a custom prefix.
This to me implies that when I request a CFC method with returnFormat=json that the prefix will be prepended to the result. However, in my tutorial, I was simply doing something like this:
<cfset str.STATUS = 200>
<cfset str.MESSAGE = "passed">
<cfoutput>#serializeJSON(str)#</cfoutput>
This by itself was enough to modify the result. Even called on a page by itself - no Ajax involved - the result is prefixed with //. This is not what I expected.
Archived Comments
I have seen it where is display \\invalidtag. The fix was in application.cfc to do this
this.securejson=false
I think in the CF administrator the default securejsoprefix is \\
Right - that's another way to turn it off if you don't have access to the CF Admin.
That's exact what I expect. SecureJSON means, for me, secure all JSON generated by CFC or serializeJSON. I wouldn't call it a bug.
I'm not calling it a bug. I'm saying it isn't what I expected. :)
I was just wondering... What exactly about prefixing a json response with \\ makes it secured? I don't understand how that secures anything. Though I can't help but think there has to be something I'm missing if Adobe took the time to implement it.
What the prefix is protecting your users from is a little known exploit call JSON Hijacking. Which I discuss in my Practical Ajax Security presentation
http://experts.adobeconnect...
The recording is cut off right as I get into the meet of the subject and the countermeasures, but the slides are available here: http://www.12robots.com/ind...
You can also see the CFUnited version of the preso here: http://www.cfmumbojumbo.com...
So essentially, JSON hijacking is a form of a Cross-Site request forgery where the end user is tricked into making a request to a secured service that returns JSON data. The hacker uses a page that he controls to request the data and the users browser makes the request. Then the data is returned (provided the users browse passes along appropriate cookies and such and the user is logged in).
The data returned can only be exploited if the end user is using an old browser (like FF 2.0 and older version of Opera, I think) and it is wrapped in an Array. The hacker overrides the Array() constructor in JavaScript and rips the data out.
Personally, I think that JSON hijacking is of very little concern to most of us and that if the prefix breaks your code then don't use it. Instead I would simply make sure that the returned data is wrapped in an object, for example {data: [1,2,3]} instead of an array and you should be protected.
Thanks Jason. That's exactly what I was going to say. Honest. (Ok, maybe not...)
Jason, thanks a lot! Long time no talk :-) Overloading the Array() method is something I actually have not thought of. Means more work for me... but I like it. Thanks for that.
Now in cross-site request forgery, it falls down to ... nevermind. http://www.12robots.com/enc... explains it well.
Alright, so the idea is to make malicious intent code to fail by prepending bogus values to the response, I guess? That sounds like a pretty weak attempt at securing things. I don't think I personally would bother with it.
I still don't understand the intent with the prefixing... And I may never. lol
"so the idea is to make malicious intent code to fail by prepending bogus values to the response, I guess? That sounds like a pretty weak attempt at securing things. "
It's not really prepending bogus values, it's putting the code into a context where it cannot be executed, which is, essentially, the same way we mitigate the risk of SQLi and XSS, right?
Well by bogus values i meant syntactically inexecutable values, which prevents it from being executed.
But I do think I understand what you are saying. Thanks a bunch! :-)