javascript字符串是不是需要“转义”字符“<”和“>”?

Posted

技术标签:

【中文标题】javascript字符串是不是需要“转义”字符“<”和“>”?【英文标题】:Is it necessary to "escape" character "<" and ">" for javascript string?javascript字符串是否需要“转义”字符“<”和“>”? 【发布时间】:2010-10-21 06:23:19 【问题描述】:

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

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

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

&lt;/script&gt;&lt;script&gt;alert('bug')&lt;/script&gt;&lt;/script&gt;

这是XSS漏洞。

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

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

JavascriptEncode所做的就是在“/”和“'”和“””之前添加字符“\”。所以,输出的html是这样的。 var username = "alert(\'bug\')";

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

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

对此有什么建议吗?

谢谢。

【问题讨论】:

【参考方案1】:

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

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

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

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

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

前段时间,我写了一点关于the hows and whys of this的文章。

【讨论】:

但 CDATA 块内 ]]&gt; 中的 &amp;gt; 仍必须由 &amp;gt; 替换。所以foo[bar[0]]&gt;1234必须替换为foo[bar[0]]&amp;lt;1234foo[bar[0]] &gt; 1234。否则 CDATA 块将过早关闭。 由于 CDATA 将 & 字符呈现为“&”而不是“实体的开始” - 那是行不通的。如果您需要在 CDATA 中表示字符串“]]>”,那么我很确定您很烂,应该使用实体开头(在 CDATA 块之外) 或者只是添加一个空格:foo[bar[0]] &gt; 1234 - 或者如果它是字符串的一部分:'foo[bar[0]]'+'&gt;1234' - 或者只是将所有脚本包含在外部 .js 文件中。【参考方案2】:

不,您不应在 HTML 中使用 &lt;script&gt; 中的 HTML 实体来转义 &lt;&gt;

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

在 XHTML 中它更复杂。

如果您将 XHTML 作为 XML 发送(与 IE 不兼容的方式)并且不使用 CDATA 块,那么除了 JavaScript 字符串转义之外,您还需要转义实体。 如果您将 XHTML 作为 XML 发送并使用 CDATA 块,则不要转义实体,而是将 ]]&gt; 替换为 ]]]]&gt;&lt;![CDATA[&gt; 以防止转义(除了 JavaScript 字符串转义)。 如果您将 XHTML 发送为 text/html(99% 的人都这样做),那么您必须同时使用 XML CDATA 块、XML CDATA 转义和 HTML 转义。

【讨论】:

+1。次要的挑剔:不是所有次出现的&lt;/ 都需要转义(尽管这可能是最简单的解决方案)。 Only the full &lt;/script string followed by any space character, &gt;, or / will end the respective opening tag.【参考方案3】:

便宜又简单的方法:

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

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

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

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

如果您只处理 ASCII。

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

【讨论】:

+1 此外,此解决方案使您的输出源代码看起来像 h4x0r!

以上是关于javascript字符串是不是需要“转义”字符“<”和“>”?的主要内容,如果未能解决你的问题,请参考以下文章

java 和 JS(javaScript)中的反斜杠正则转义

javascript 星号转义符

转义 JavaScript 字符串中的单引号以进行 JavaScript 评估

在 JavaScript 中转义字符串

javascript 之基础

htmljavascripturl特殊字符的转义诠释及使用方法详解