清理<script>元素内容

时间:2015-09-27 01:32:07

标签: html xss sanitization

假设我想通过动态&lt; script&gt; 元素向我的客户端提供一些数据(在第一个响应中,没有延迟)。

&#xA;&# xA;
 &lt; script&gt;&lt;%= payload%&gt;&lt; / script&gt;&#xA;  
&#xA;&#xA;

说出来 payload 是字符串 var data ='&lt; / script&gt;&lt; script&gt; alert(“Muahahaha!”)';&lt; / script&gt; 。结束标记(&lt; / script&gt; )将允许用户将任意脚本注入我的页面。如何正确清理脚本元素的内容?

&#xA;&#xA;

我想我可以将&lt; / script&gt; 更改为&lt; \ / script&gt; &lt;! - &lt; \! - 。还有其他危险的字符串我需要逃脱吗?有没有更好的方法来提供这种“冷启动”数据?

&#xA;

2 个答案:

答案 0 :(得分:1)

编辑非数据突变。

如果我正确地解释了这一点。您希望阻止用户在用户提交的字符串中过早地结束script标记。正如您所说的那样,可以使用结尾标记<\/script>添加反斜杠来完成html。在这种情况下,这是你应该担心的唯一逃避。您不应该转义html注释,因为浏览器会将其解释为javascript的一部分。也许如果某些较旧的浏览器不能正确解释脚本标记,则默认为text/javascript类型(language="javascript"已弃用),可能需要添加type='text/javascript'

根据Mike Samuel的回答here我可能错误地认为不需要逃避HTML评论。但是我无法用铬或铬来复制它。

答案 1 :(得分:1)

假设您正在执行此操作:

Payload设置为

var data = '[this is user controlled data]';

并且其余代码(赋值,引号和分号)由您的应用程序生成,然后您想要的编码是十六进制实体编码。

有关详细信息,请参阅OWASP XSS Prevention Cheat Sheet, Rule #3。这将转换

</script><script>alert("Muahahaha!")

var data = '\x3c\x2fscript\x3e\x3cscript\x3ealert\x28\x22Muahahaha\x21\x22\x29';

尝试这一点,您将看到这样做的好处是无论用户设置字符串包含哪些字符,都可以完全正确存储。此外,它还负责单引号和双引号编码。作为超级奖励,它也适合存储在HTML属性中:

<a onclick="alert('[user data]');" />

通常必须再次进行HTML编码才能正确显示(因为HTML属性中的&amp;被解释为&)。但是,十六进制实体编码不包含任何具有特殊含义的HTML字符,因此您可以以一个价格获得两个。

从评论更新

OP指出服务器端代码将以

的形式生成
var data = <%= JSON.stringify(data) %>;

以上仍然适用。 JSON类可以正确地对实体编码值进行十六进制,因为它们会插入到JSON中。这不容易在课外进行,因为您必须再次有效地解析JSON以确定当前语言上下文。我不建议选择在</script>中转义正斜杠的简单选项,因为还有其他序列可以结束语法上下文,例如CDATA closing tags。正确逃离,您的代码将来会证明并且安全。