Prefix Serialized JSON aka "secureJSON"

Hello wonderful Lucee devs!

Migrating an ACF 10 instance with a RESTful API to Lucee.

ACF 10 has option to “prefix serialized JSON” with characters, as a way to prevent raw web scraping / XSS, and we implemented this. However, I do NOT see this functionality in Lucee. Nor do I see it mentioned here in dev forums, SO, Google, anywhere. The only ‘reference’ to anything with secureJSON with Coldfusion is ACF specific here: Prefix Serialized JSON in ColdFusion. I tried setting the secureJSON but again I think that’s unique to the ACF interpreter, as it doesn’t seem to make a difference.

Our APIs – used far and wide in deployed applications, including our Android and iPhone apps – expect these leading characters and strip them out, and we want to preserve this.

I tried a number of string modifications, such as manually prefixing this and just cfoutputting a string. However, returning / outputting a string QUOTES the entire thing, with leading and end double quotes, whereas the JSON response is not quoted.

I’m sure there’s some manual way to deal with this, but as we have many dozens of API endpoints and multiple applications consuming, it’s rather tedious and time-consuming and was hoping to see if anyone had any experience with this, or whether it may qualify as an improvement proposal.

OS: Windows Server 2016 and 2019
Java Version: Java 11.0.11 AdoptOpenJDK 64bit, and JRE 8 build 301 (8.0.3010.9)
Tomcat Version: Apache Tomcat 9.0.46
Lucee Version:

1 Like

Whatever security you think the JSON prefix is affording you, I’ve never understood a single purpose for it; as evidenced by the fact that you simply strip it off anyway. No one has ever been able to articulate a single actual benifit or reason for the JSON prefix. So far as I can tell, it’s just some thing Adobe did years ago for “reasons” and everyone went along with it because it had “something to do with security”.

To my knowledge, Lucee never implemented a JSON prefix because it was a terrible idea that did nothing at all for security in the first place. I would recommend you change your clients to only strip the // if it exists.

You can always manually append random characters to your JSON if it helps you, but you’d need to do your own JSON serialization and concatenate it yourself. You haven’t really shared how your APIs are built so I can’t help much further. I can say you’ll not be able to use any of the built in “return format of JSON” tricks when hitting a CFC as a remote method call.

1 Like

Thanks for taking the time to reply!

The prefix provides some basic XSS prevention for less secure designs, but in between CORS and our authenticated endpoints, we don’t really need it. It was a design choice from before my time that I’m forced to work around now.

We have dozens of components, hundreds of functions, and multiple applications across multiple teams and segments that all expect it to work that way, so it’s not as easy as “changing your clients” and more like coordinating a massive upgrade across our org for everything that relies on our APIs.

Back to the subject at hand: I did do a string concatenation to manually prepend, but the cfreturn / cfoutput returns the entire string quoted… going to see if I can use strpos methods to strip those, or alternate ways to build / return the output without resorting to rewriting a serialization lib.

Please, do explain. Because I’m not aware of any protection at all. The prefix was added way back in the day before it was standardized to have JSON parsing funtionality in browsers so the concern was you may blindly pass the results of an API call into JS’s eval() function and unwittingly run malicious JS code. Of course, the giant holes in this logic are

  • Everyone just strips off the // anyway, so if there was malicious JS in the string, it would still get eval’d! eval() is going is going to be susceptible regardless of whether there’s a prefix.
  • No one I know of has actually used eval() since the early 2000’s so I’ve never seen an app that would even be susceptible to this sort of attack. JSON.parse( string ) isn’t going to be susceptible regardless of whether there’s a prefix.
  • The JSON is coming from your own web service, so if it had malicious bits in it, they’d be coming from you!

This is literally just like in the movie Megamind where Minion and Megamind speak in “code” by simply saying the word “code” prior to every sentence.

This, of course, offers zero security as it neither obscures the contents of the message, nor verifies the integrity of the message that follows. It’s just a meaningless prefix you strip off and then treat the message like you would have in the first place.

Maybe for you it isn’t. For me it was in the past. The last couple times I ran into this, it was sites using JQuery and I just registered a global listener on the website that pre-processed all $.ajax() responses that had a content type of JSON and started with //. Something along the lines of:

$.ajaxSetup( {
  dataFilter: function(data, type){
    // TODO: Check content type and data contents 
    return data.substring(2, data.length);
} );

Yep, and like I said above, until you show us your code, I can’t tell what you’re doing. But again, I assume you’re using something along the lines of

remote function foo() returnFormat='json' {

And like I said above, that won’t work. You need to change the function’s returnFormat to plain and then it won’t touch your custom-built JSON by trying to serialize it again.

remote function foo() returnFormat='plain' {
  return '//' & serializeJSON( data );

Thanks again Brad for taking the time to reply. I really appreciate your insight and recommendations. The example to returnFormat ‘plain’ and manually pre-pend the characters was perfect, and after tinkering with the returnFormat and the produces=“text/json”, I was able to get this to work as we needed.