Reputation: 1130
Let's say I have following script tag in my html document:
<script type="application/json" id="stuff">
{
"unicorns": "awesome",
"abc": [1, 2, 3]
}
</script>
and I'm parsing this JSON in my application. Someone told me that ...
This method of embedding json in a script tag has a potential security issue. Assuming the json data originated from user input, it is possible to craft a data member that will in effect break out of the script tag and allow direct injection into the dom. See here:
<script type="application/json" id="stuff">
{
"unicorns": "awesome",
"abc": [1, 2, 3],
"badentry": "blah </script><div id='baddiv'>I should not exist.</div><script type="application/json" id='stuff'> ",
}
</script>
I need to embedd a JSON in a script tag, but I don't know how I should do that, without leaking security vulnerables.
Thanks for helping.
Upvotes: 2
Views: 2370
Reputation: 18559
To include JSON in a script element, then you need to ensure the data can't contain the closing tag. Check that '<' in any keys or values is encoded as '\u003c'. Then parse the contents using JSON.parse.
You'd also need to ensure that the data for individual string values don't escape the string, so escape quotes and backslashes too.
The surrounding context can also cause issues as the correct encoding can depend on the nesting of outer elements. Quotes, html entities, unicode line and paragraph separators, and CDATA close tags can require encoding. To be safe, you can use these hex escapes for any non-alphabetic characters.
Your server-side language should have some function to encode JSON like this. But they're not all designed for security so make sure it encodes all these characters.
Upvotes: 5
Reputation: 6991
Because javascript, inherently runs on the client side you can never trust anything a client does with it.
So this sounds like user input or possible user input, as with everything you do on a server it means you will have to do proper vetting of any user input that is sent to you. As far as I can tell JSON.parse
is considered decently secure. So any objects sent to your service should be parsed using it.
After this you'd probably have to do some more input cleaning. Make sure you always escape HTML when you print it to the browser.
Upvotes: 1