My question is very similar to this one, but without the <% %>
details.
Let's say I have the following code:
public static IHtmlString AddSomethingToWindow(string value) {
var output = new StringBuilder();
output.AppendLine("<script type='text/javascript'>");
output.Append("window.something=\"" + value + "\";");
output.Append("</script>");
return new HtmlString(output.ToString());
}
Let's say value
is coming from an untrusted source & could be anything.
To make RenderSomething
method safe, do I need HttpUtility.HtmlEncode(HttpUtility.JavaScriptStringEncode(value))
or is just HttpUtility.JavaScriptStringEncode(value)
sufficient? Or are both wrong?
I strongly believe, although I'm not 100% sure, that JavaScriptStringEncode
is enough.
(1) From HTML spec:
The easiest and safest way to avoid the rather strange restrictions described in this section is to always escape an ASCII case-insensitive match for "<!--" as "\x3C!--", "<script" as "\x3Cscript", and "</script" as "\x3C/script"...
(2) The core idea of this is supported by answers from other people 1 & 2, even though they may not be fully accurate or up to date with the spec comment above (from which the second linked answer is actually derived).
(3) Looking at JavaScriptStringEncode
, it seemingly replaces <
, among other characters, which should satisfy (1).
From these 3 points, I think one can conclude that calling JavaScriptStringEncode
is enough, since the code inside script doesn't need to be HTML encoded, it just needs to escape <!--
, <script
, and </script
(case-insensitively), which JavaScriptStringEncode
by escaping <
(replacing it with its Unicode sequence).