0

In CF (9.0.2 with esapi-2.0_rc10.jar):

<cfset test = ['ha"ha"']>
<script>
  x = JSON.parse('#encodeForJavaScript(serializeJSON(test))#');
  y = JSON.parse('#replace(serializeJSON(test), '"', '\"', "all")#');
  z = #serializeJSON(test)#;
  j = JSON.parse('#jsStringFormat(serializeJSON(test))#');
</script>

Output:

<script>
  x = JSON.parse('\x5B\x22ha\x22ha\x22\x22\x5D');
  y = JSON.parse('[\"ha\\"ha\\"\"]');
  z = ["ha\"ha\""];
  j = JSON.parse('[\"ha\\\"ha\\\"\"]');
</script>

y, z and j are valid.

x actually fails: "Uncaught SyntaxError: Unexpected token h "

I thought encodeForJavaScript() in ESAPI was supposed to be the best and safest function to be used in situation like this. Why does it fail here?

side question, if I'm only using serializeJSON(), even if the data is dynamically built with user input, does it mean I don't really need to use JSON.parse since there will be no functions in the JSON string for sure?

Henry
  • 32,689
  • 19
  • 120
  • 221

2 Answers2

2

If you use encodeForJavascript on a JSON string, then it is no longer valid JSON.

Sean Coyne
  • 3,864
  • 21
  • 24
  • so I should use `encodeForJavascript` everywhere inside a script blog, except when it's a valid JSON string? – Henry Jul 20 '12 at 19:10
  • 2
    Yes you should use it for javascript strings that you want to output to the source, but in your use case, you could just do x = #serializeJson(test)#; and it should work fine because you are JSON encoding an array and the result should be a valid Javascript array. – Sean Coyne Jul 20 '12 at 19:16
  • That said, if "test" is user provided data from the form or url scope, or otherwise "unsafe" then you could use other methods to clean it up for security purposes. I'm not advocating directly outputting unsafe data just explaining why what you have is invalid javascript. – Sean Coyne Jul 20 '12 at 19:17
  • If the CF data are all constructed from user inputs, like you said, do you think case `j` would be more secure than case `z`? Or is it really unnecessary? – Henry Jul 20 '12 at 19:20
  • No, I think your j example will eventually end up in the same situation. Your very basic example might "work" because there simply isn't enough to expose the problem, but, in general, if you take a valid JSON string and then modify it, you could possibly end up with a string that is no longer valid JSON. – Sean Coyne Jul 20 '12 at 19:25
  • 2
    `encodeForJavascript` was designed to encode a plain string to make it safe for output within a Javascript string, not encode a valid JSON string (which is a very specific, defined format). – Sean Coyne Jul 20 '12 at 19:27
0

Quote from JSON.org:

A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.

This is in the JSON context

This pic 'shows' the format for strings in json objects

See json.org for more info

A Person
  • 1,350
  • 12
  • 23