Json: PHP to JavaScript safe or not?

In terms of pure JavaScript, yes, you are safe: the output of json_encode can never containing anything but static values which will have no unexpected side effected when passed to eval. (Though you typically have to surround your JSON string with () when using eval, to avoid it misinterpreting an object literal expression as a statement block.)

Aside: this is not necessarily true of all JSON encoders because there are some characters that are valid to include raw in a JSON string that are not valid raw in JavaScript. Most notably, U+2028 and U+2029 which can’t go unescaped in JavaScript string literals as they constitute newlines. However PHP’s encoder encodes all non-ASCII characters (eg as "\u2028") so no issue here.

In terms of JavaScript embedded in another language (typically: HTML) you are not necessarily safe. For example:

<script type="text/javascript">
    var v= <?php echo json_encode($value); ?>;
</script>

In this example, what if value contains a string with the character sequence </script? This would allow the value to end the script block prematurely and thus escape into HTML markup, where it could then inject other malicious script.

To avoid this problem, when including JSON content in HTML, always encode the < character in string literals, as \x3C or, in JSON-compliant terms, \u003C. For compatibility with XHTML non-CDATA script blocks, do & as well. For compatibility with JS inside event handler attributes, do quotes as well.

PHP will do this for you with the right options to json_encode():

var v= <?php echo json_encode($value, JSON_HEX_QUOT|JSON_HEX_TAG|JSON_HEX_AMP|JSON_HEX_APOS); ?>;

(You may want to define a shortcut function to make this quicker to write.)

Leave a Comment