Question

How do I properly encode JavaScript in the following context:

<html>
...
<script type="text/javascript">
var settings = @Html.PleaseEncode(settings.ToJson());
// ...
</script>
</html>

The values in my JSON objects are set by the application administrator, so I assume they need properly encoded -- both for HTML and JavaScript.

I'm using System.Web.Script.Serialization.JavaScriptSerializer to do the JSON encoding. It looks like JavaScriptSerializer does some encoding as it outputs the text <None> as \u003cNone\u003c, but I'm not sure how safe it is. Right now, I'm using @Html.Raw as it works given safe input. It generates the following:

var settings = {"UnselectedReason":"None Selected", /*...*/};

If I use @Html.Encode I then get:

var settings = {&amp;quot;UnselectedReason&amp;quot;:&amp;quot;None Selected&amp;quot;, /*...*/};

I've tried with and without AntiXSS but I see no difference either way.

Was it helpful?

Solution

AntiXSS has JavaScriptEncode, but it's designed for individual items, rather than taking a whole set of, err, settings.

So if you passed in {"UnselectedReason":"None Selected", /.../} it'd eat the quotes and other things, which is probably not what you want. Instead what I'd do is in your ToJson I'd build the settings up with a string builder, something like

StringBuilder sb = new StringBuilder();
sb.Append("{");
foreach(KeyValuePair kv in mySettings)
{
    sb.Append("\"");
    sb.Append(Microsoft.Security.Application.Encoder.JavaScriptEncode(kv.Key, true);
    sb.Append(":");
    sb.Append(Microsoft.Security.Application.Encoder.JavaScriptEncode(kv.Value, true);
    sb.Append("\",");
}

string outputString = sb.ToString().TrimEnd(",") + "}";

return new HtmlString(outputString);

Note: Code is off the top of my head and hasn't been even typed into VS. It illustrates the principal and may well not compile!

OTHER TIPS

If you are wanting to use the JS, why are you trying to encode it? If you have json, it should already be encoded. Since its JS, you shouldn't require html encoding on it either.

I don't believe you need to encode here, unless you can provide a case why and I'm just missing something?

With any valid javascript you could run the risk of injection, but since you know this is coming from some valid source (ie model) that is getting encoded the path is relatively safe to get the JSON.

It should be safe for direct output...

<script>//<![CDATA[<!--

var settings = @Html.Raw(settings.ToJson());

//-->]]></script

Though if you are really concerned... this assumes a modern browser or json2.js is included.

<script>

var settings = JSON.parse("@Html.Raw(Server.UrlEncode(settings.ToJson()))");

</script

It will be safe. It won't destroy your markup.

If you are sure about what you want to do:

@Html.Raw(yourStringWithTheJSONcode)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top