Interesting JSON issue to look out for - and a cffileupload bug

This post is more than 2 years old.

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.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by MikeG posted on 4/20/2011 at 2:22 AM

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 \\

Comment 2 by Raymond Camden posted on 4/20/2011 at 5:16 AM

Right - that's another way to turn it off if you don't have access to the CF Admin.

Comment 3 by Patrick Heppler posted on 4/20/2011 at 1:52 PM

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.

Comment 4 by Raymond Camden posted on 4/20/2011 at 3:12 PM

I'm not calling it a bug. I'm saying it isn't what I expected. :)

Comment 5 by Aaron DeRenard posted on 4/21/2011 at 6:21 PM

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.

Comment 6 by Jason Dean posted on 4/21/2011 at 7:32 PM

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.

Comment 7 by Raymond Camden posted on 4/21/2011 at 7:38 PM

Thanks Jason. That's exactly what I was going to say. Honest. (Ok, maybe not...)

Comment 8 by Aaron DeRenard posted on 4/21/2011 at 8:16 PM

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

Comment 9 by Jason Dean posted on 4/21/2011 at 8:21 PM

"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?

Comment 10 by Aaron DeRenard posted on 4/21/2011 at 9:58 PM

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! :-)