Reputation: 357
Given an object: {"key":"pairs","are":"fun"}
that is echoed into a variable like const foo = <?php echo $bar ?>;
. What is the proper way to escape the object? I've tried encode_json
which escapes all the double quotes {\"key\":\"pairs\",\"are\":\"fun\"}
disallowing the object to render. I have also tried esc_js
which converts the double quotes to & quot;
. How do i properly escape the object and return the object to foo
? The out should be {"key":"pairs","are":"fun"}
escaped of any malicious content.
Upvotes: 0
Views: 1583
Reputation: 4029
If you use wp_json_encode
to produce the JSON string itself, the output where you assign the JSON to a JavaScript variable in the browser should be reasonably safe. The wp_json_encode
function will escape the characters that might otherwise allow someone to inject code at the point of assignment.
However, you also have to consider how your values in the key/value pairs will be used. If you're expecting an integer, maybe run the value through intval
or if you are expecting plaintext that you're injecting into the page later, perhaps run it through esc_html
.
For example:
<?php
$map = [
'key' => 'pairs',
'are' => '"; I document.write(\'fun trying to break out\')',
'i_am_expecting_plaintext' => esc_html('<a href="evillinkhere">Hello</a><script>evilscript();</script>'),
'i_expect_an_integer' => intval("90i"),
'some_html_allowed' => wp_kses('<a href="http://nisamerica.com/">here</a><script>dangerous();</script>', ['a' => array('href'=>array())]),
];
?>
<script>const foo = <?php echo wp_json_encode($map, JSON_PRETTY_PRINT); ?>;</script>
Produces the following output:
<script>const foo = {
"key": "pairs",
"are": "\"; I document.write('fun trying to break out')",
"i_am_expecting_plaintext": "<a href="evillinkhere">Hello<\/a><script>evilscript();<\/script>",
"i_expect_an_integer": 90,
"some_html_allowed": "<a href=\"http:\/\/nisamerica.com\/\">here<\/a>dangerous();"
};</script>
Addendum:
The reason wp_json_encode
was giving you {\"key\":\"pairs\",\"are\":\"fun\"}
before is that you were providing it a string that was already in JSON-notation. What wp_json_encode
does is take native PHP variables and escape them as JSON. It's a pretty thin wrapper around json_encode
really. My suggestion above is really to just produce the map in PHP, and feed that to the encode function instead of making your string representation and then trying to make it safe.
Upvotes: 1