事实证明以下看起来像有效的javascript,不是:
<html>
<body>
<script>
json = {test: "</script><script>alert('hello');</script>"};
</script>
</body>
</html>
相同的文本,当通过ajax api返回JSON时,正如预期的那样工作。但是,当在线渲染时会导致基本的XSS问题。
给定一个任意正确的JSON字符串,我需要做什么服务器端才能使其在线呈现安全?
修改 理想情况下,我希望修复程序也可以使用以下字符串:
json = {test: "<\/script><script>alert('hello');<\/script>"};
意思是,我不知道我的底层库是如何编码/
char的,它可能已选择对其进行编码,或者它可能没有。 (所以它的正则表达式修复可能更强大)
答案 0 :(得分:5)
见OWASP's XSS prevention guide(参见规则#3) -
除字母数字字符外, 转义小于256的所有字符 用\ xHH格式来防止 切换出数据值 脚本上下文或另一个 属性。不要使用任何逃脱 像“因为引用”这样的快捷方式 HTML可以匹配字符 首先运行的属性解析器。
假设这是你的对象的样子 -
var log = {
trace: function(m1, m2, m3){},
debug: function(m1, m2, m3){},
currentLogValue : "trace {].a23-%\/^&",
someOtherObject : {someKey:"somevalue", someOtherKey:"someothervalue"}
};
这最终会像这样 -
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"}
};
规则很简单 -
这可确保不受信任的数据始终被解释为字符串,而不是函数/对象/其他任何内容。
答案 1 :(得分:4)
首先,这根本不是JSON,它是一个Javascript对象。 JSON是一种基于Javascript语法的文本格式。
您可以确保代码不包含</
字符组合:
var obj = { test: "<"+"/script><script>alert(\"hello\");<"+"/script>" };
或者如果您使用XHTML,您可以确保脚本标记中的内容被解释为纯数据:
<script type="text/javascript">
//<![CDATA[
var obj = { test: "</script><script>alert(\"hello\");</script>" };
//]]>
</script>
答案 2 :(得分:2)
在文字字符串中,在所有“不安全”字符前添加反斜杠(\
),包括“</script>
”中出现的正斜杠(/
→\/
)。
这会将您的示例更改为:
json = {test: "<\/script><script>alert(\"hello\");<\/script>"};
它仍然是有效的JSON。
当然你也必须逃避双引号("
→\"
)和反斜杠本身(\
→\\
),但你已经有了无论如何要这样做。您还应该考虑转发单引号('
→\'
)以确保安全。
答案 3 :(得分:2)
您可能遇到的一个问题是浏览器上的HTML和JavaScript解释器是交错运行的。
<html>
<body>
<script>
json = {test: "</script><script>alert('hello');</script>"};
</script>
</body>
</html>
在您的示例中,HTML解释器会将json = {test: "
提供给js解释器,然后它会找到下一个javascript块(由<script>
和</script>
标记分隔)并提供{{ 1}}到js解释器。 alert('hello');
标记在javascript字符串中并不重要,因为HTML解释器是查找js代码块并且不理解js字符串的那个。
第一部分将导致js语法错误,而第二部分将创建警报。我意识到这并没有回答你该怎么做的问题,但也许它会更清楚地说明幕后发生的事情。
答案 4 :(得分:1)
我找到了this要为JSON字符串转义的字符列表:
\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
使用PHP?如果是这样的话:json_encode
echo json_encode("<\/script><script>alert(\"hello\");<\/script>");
输出:
"<\\\/script><script>alert(\"hello\");<\\\/script>"
另一个例子:
echo json_encode("</script><script>alert(\"hello\");</script>");
输出:
"<\/script><script>alert(\"hello\");<\/script>"