17

有时,服务器端会生成嵌入到内联 JavaScript 代码中的字符串。例如,如果“用户名”应该由 ASP.NET 生成。然后看起来像。

<script>
   var username = "<%UserName%>";
</script>

这是不安全的,因为用户可以拥有他/她的名字

</script><script>alert('bug')</script></script>

这是XSS漏洞。

所以,基本上,代码应该是:

<script>
   var username = "<% JavascriptEncode(UserName)%>";
</script>

JavascriptEncode所做的是在“/”和“'”和“””之前添加字符“\”。因此,输出html就像.var username = "</script>alert(\'bug\')</script ></脚本>";

浏览器不会将“ </script> ”解释为脚本块的结尾。所以,XSS 在避免。

但是,那里仍然有“<”和“>”。建议也转义这两个字符。首先,我不认为将“<”更改为“<”是一个好主意 和 ">" 到 ">" 这里。而且,我不确定将“<”更改为“\<”和将“>”更改为“\>”是否可以被所有浏览器识别。似乎没有必要对“<”和“>”进行进一步的编码。

对此有什么建议吗?

谢谢。

4

3 回答 3

16

根据您使用的标记语言,该问题有不同的答案。

如果您使用的是 HTML,那么您不能用实体来表示它们,因为脚本元素被标记为包含 CDATA。

如果您使用的是 XHTML,那么您可以将它们表示为带有显式 CDATA 标记的 CDATA,或者您可以将它们表示为实体。

如果您使用 XHTML,但将其作为 text/html 提供,那么您需要编写符合 XHTML 规则但仍可使用 text/html 解析器的内容。这通常意味着使用显式 CDATA 标记并在 JavaScript 中将它们注释掉。

<script type="text/javascript">
// <![CDATA[
  …
// ]]>
</script>

前段时间,我写了一些关于这个的方法和原因的文章。

于 2009-04-23T08:06:50.647 回答
14

不,您不应该在 HTML 中转义<>使用 HTML 实体<script>

  • 使用 JavaScript 字符串转义规则(\\\"替换\"
  • 并将所有出现的 , 替换为</,<\/以防止逃出<script>元素。

在 XHTML 中它更复杂。

  • 如果您将 XHTML 作为 XML 发送(与 IE 不兼容的方式)并且不使用 CDATA 块,那么除了 JavaScript 字符串转义之外,您还需要转义实体。
  • 如果您将 XHTML 作为 XML 发送并使用 CDATA 块,则不要转义实体,而是替换]]>]]]]><![CDATA[>以防止转义(除了 JavaScript 字符串转义)。
  • 如果您发送 XHTML text/html(99% 的人都这样做),那么您必须同时使用 XML CDATA 块、XML CDATA 转义和 HTML 转义。
于 2009-05-25T20:40:23.047 回答
2

便宜又简单的方法:

<script type="text/javascript">
    var username = "<%= Encode(UserName) %>";
</script>

其中的编码方案Encode是将输入的每个字符转换为\xABCD与 JavaScript 兼容的相关表示。

另一种便宜又简单的方法:

<script type="text/javascript">
    var username = decodeBase64("<%= EncodeBase64(UserName) %>");
</script>

如果您只处理 ASCII。

当然,pst以严格的方式一针见血。

于 2009-10-02T19:11:39.533 回答