0

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?

12
  • 1
    Simplest thing would be a JSON encoder, because valid JSON is valid JavaScript (and it's safe). Commented Dec 3, 2024 at 13:31
  • encoding does not change anything in regards to some script security - script is script, and by encoding it, you do not change the security aspect here at all, just that funny characters such as spaces etc. can be correctly encoded. So, if you encode un-safe script, well, then you have some unsafe script. So, encoding really has little to do with security issues, only that of having some encoded script that will work. Commented Dec 3, 2024 at 15:14
  • @AlbertD.Kallal I've updated the question to make it clearer. Please, take a look at edit history. The purpose here is to include value as part of a JS string, not include it as any JS code. Commented Dec 3, 2024 at 17:45
  • 1
    "Let's say value is coming from an untrusted source & could be anything." <- then you shouldn't be injecting this as a script. Commented Dec 3, 2024 at 17:58
  • 1
    @HossamEl-Deen not correct: a proper JSON serializer always renders "/" as "\/" Commented Dec 4, 2024 at 0:45

1 Answer 1

0

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).

Screenshot of JavaScriptStringEncode implementation that makes a call to a method called CharRequiresJavaScriptEncoding for each character of the string and replaces such cases with their unicode character Screenshot of CharRequiresJavaScriptEncoding implementation which takes a character and checks whether it's, among other characters, an opening angle bracket

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).

Sign up to request clarification or add additional context in comments.

1 Comment

This is true. The HTML parser will pay absolutely no attention to the content of the <script> tag other than to scan for "</script>". Thus, HTML encoding is not necessary is there is no HTML parsing involved.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.