最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - What is the correct way to encode an inline javascript object, in order to protect it from XSS? - Stack Overflow

programmeradmin2浏览0评论

It turns out the following which looks like valid javascript, is not:

<html> 
<body>
<script>
 json = {test: "</script><script>alert('hello');</script>"};
</script>
</body>
</html>

The same text, when returned JSON via an ajax api works just as expected. However when rendered in-line results in a basic XSS issues.

Given an arbitrary correct JSON string, what do I need to do server side to make it safe for in-line rendering?

EDIT Ideally I would like the fix to work with the following string as well:

json = {test: "<\/script><script>alert('hello');<\/script>"};

Meaning, I have no idea how my underlying library is encoding the / char, it may have chosen to encode it, or it may have not. (so its likely a regex fix is more robust)

It turns out the following which looks like valid javascript, is not:

<html> 
<body>
<script>
 json = {test: "</script><script>alert('hello');</script>"};
</script>
</body>
</html>

The same text, when returned JSON via an ajax api works just as expected. However when rendered in-line results in a basic XSS issues.

Given an arbitrary correct JSON string, what do I need to do server side to make it safe for in-line rendering?

EDIT Ideally I would like the fix to work with the following string as well:

json = {test: "<\/script><script>alert('hello');<\/script>"};

Meaning, I have no idea how my underlying library is encoding the / char, it may have chosen to encode it, or it may have not. (so its likely a regex fix is more robust)

Share Improve this question edited Aug 23, 2010 at 1:20 Sam Saffron asked Aug 16, 2010 at 0:25 Sam SaffronSam Saffron 131k81 gold badges333 silver badges510 bronze badges 3
  • Basically, if you want to render it in-line, you need to make sure it doesn't contain the character sequence </script>. – Anon. Commented Aug 16, 2010 at 0:28
  • or </ScRipt> I guess ... I worry about performance with a simple string concatenation fix and also that there may be other weird issues I am not aware of – Sam Saffron Commented Aug 16, 2010 at 0:30
  • Unless there is something strange going on, the underlying library does not escape the slash character. It has no special meaning in a Javacript string, so there is no reason to escape it. – Guffa Commented Aug 16, 2010 at 1:14
Add a comment  | 

5 Answers 5

Reset to default 6

See OWASP's XSS prevention guide (See Rule #3) -

Except for alphanumeric characters, escape all characters less than 256 with the \xHH format to prevent switching out of the data value into the script context or into another attribute. Do not use any escaping shortcuts like \" because the quote character may be matched by the HTML attribute parser which runs first.

Assume this is how your object looks like -


var log = {
trace: function(m1, m2, m3){},
debug: function(m1, m2, m3){},
currentLogValue : "trace {].a23-%\/^&",
someOtherObject : {someKey:"somevalue", someOtherKey:"someothervalue"}
};

This should end up like this -


var log = {
trace : "function\x28m1,\x20m2,\x20m3\x29\x7B\x7D",
debug : "function\x28m1,\x20m2,\x20m3\x29\x7B\x7D",
currentLogValue : "trace\x20\x7B\x5D.a23\x2D\x25\x5C\x2F\x5E\x26",
someOtherObject : {someKey : "somevalue", someOtherKey:"someothervalue"}
};

The rules are straightforward -

  1. Untrusted data is only allowed within a pair of quotes
  2. Whatever is within quotes gets escaped as follows - "Except alphanumeric characters, escape everything else with the \xHH format"

This ensures that untrusted data is always interpreted as a string, and not as a function/object/anything else.

To start with, this is not JSON at all, it's a Javascript object. JSON is a text format that is based on the Javascript syntax.

You can either make sure that the code doesn't contain the </ character combination:

var obj = { test: "<"+"/script><script>alert(\"hello\");<"+"/script>" };

Or if you are using XHTML you can make sure that the content in the script tag is interpreted as plain data:

<script type="text/javascript">
//<![CDATA[
var obj = { test: "</script><script>alert(\"hello\");</script>" };
//]]>
</script>

In literal strings, put a backslash (\) before all “unsafe” characters, including the forward slash which occurs in “</script>” (/ → \/).

This would change your example to:

json = {test: "<\/script><script>alert(\"hello\");<\/script>"};

and it would still be valid JSON.

Of course you also have to escape the double-quote (" → \") and the backslash itself (\ → \\), but you would already have to do that anyway. You should also consider escaping the single-quote (' → \') to be on the safe side.

One issue you might be running into is the fact that the HTML and javascript interpreters on the browser run interleaved.

<html> 
<body>
<script>
 json = {test: "</script><script>alert('hello');</script>"};
</script>
</body>
</html>

In your example, the HTML interpreter will give json = {test: " to the js interpreter and then it will find the next javascript block (delimited by <script> and </script> tags) and give alert('hello'); to the js interpreter. It doesn't matter that the </script> tag is in a javascript string, because the HTML interpreter is the one looking for js code blocks and doesn't understand js strings.

The first section will cause a js syntax error, while the second section will create the alert. I realize this doesn't answer your question of what to do, but perhaps it will shed more light on what is going on under the hood.

I found this list of characters to be escaped for JSON strings:

\b  Backspace (ascii code 08)
\f  Form feed (ascii code 0C)
\n  New line
\r  Carriage return
\t  Tab
\v  Vertical tab
\'  Apostrophe or single quote
\"  Double quote
\\  Backslash character

Using PHP? If so: json_encode

 echo json_encode("<\/script><script>alert(\"hello\");<\/script>");

Output:

 "<\\\/script><script>alert(\"hello\");<\\\/script>"

Another example:

 echo json_encode("</script><script>alert(\"hello\");</script>");

Output:

 "<\/script><script>alert(\"hello\");<\/script>"

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论