I use the Newtonsoft library to convert C# objects into JSON. Is this use of Newtonsoft.Json.JsonConvert.SerializeObject
secure, or is additional encoding necessary? If additional encoding is needed, what do you suggest?
Here is how I use it in a Razor view:
<script type="text/javascript">
var jsModel = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model))
</script>
I made this JsonConverter that encodes all strings with Microsoft Web Protection Library-library (aka AntiXSS-library) (http://wpl.codeplex.com/):
Usage:
Using
@Html.Raw
alone like the question does is definitely dangerous. Here is another way to safely output a model within<script></script>
tags. I followed @Levi's example to depend on the browser's faculties, as well as Microsoft's security features, and came up with this:I used the following very simple test. If I were only using
@Html.Raw
like in the question the "Bad" alert appears. Wrapped up in this way, I have valid JavaScript and the alert does not appear.The next step would be to wrap this up in a reusable HtmlHelper extension method.
Thought to drop a line of code or two based on Torbjörn Hansson's golden answer:
And here are some examples on how to use it (and when not to use it):
And last but not least:
Hope this helps.
I don't think it's necessarily unsafe here but it depends on the data. If you data has been sanitized, which it always should if it came from an outside source, then you are probably fine. The fact that it's going into a javascript object and not rendered as HTML obscures things a bit but it still comes down to your level of trust with the data being output.
You will at the very least need to perform additional encoding of the '<' character to '\u003C' and the '>' character to '\u003E'. Last I checked JSON.NET did not encode these characters in string literals.
I'm probably going to get flak for this, but the way I would do this is to render a dummy element onto the page:
Then, in Javascript, extract the data-json attribute value from the the-div element and
JSON.parse
it. The benefit to this is that you don't need to worry about which characters require special encoding. TheSerializeObject
method guarantees that the JSON blob is well-formed, and the@
operator guarantees that any remaining non-HTML-safe characters left over from the JSON conversion are properly escaped before being put into the HTML attribute (as long as the attribute value is surrounded by double quotes, as above). So yes, it's a little uglier, but it is effective at completely shutting down an entire class of vulnerabilities.