1

我有一段 JavaScript 字符串,来自不受信任的来源,嵌入在 onclick 标记中,我不确定编码该字符串的正确方法是什么。这是 HTML 的简化:

<input type="button" onclick="alert([ENCODED STRING HERE]);"
    value="Click me" />

我使用包含多种编码方法的Microsoft AntiXss 库。文本嵌入在 HTML/XML 属性中,因此使用AntiXss.XmlAttributeEncode方法对 XML 属性进行编码似乎很合适。但是,它也是一段 JavaScript。因此,使用AntiXss.JavascriptEncode方法的 JavaScript 编码 似乎也很合适。

我应该选择哪种方式,既不暴露安全漏洞,又允许正确显示文本?


更新: 我目前使用的解决方法是XmlAttributeEncode在此文本上使用并将其放在标签的自定义属性中。之后,我使用一些 JavaScript 从这个标签中读取它。它基本上看起来像这样:

<input type="button" onclick="alert(this.getAttribute('comment');"
    value="Click me" comment="[XML ATTRIBUTE ENCODED TEXT HERE]" />

虽然这完美地工作并解决了问题,但我仍然很好奇如何在 XML 属性中正确编码 JavaScript。

4

3 回答 3

5

正确的答案是对文本进行双重编码。首先是JavascriptEncode,然后是XmlAttributeEncode。这背后的基本原理是 xml/html 属性中的所有内容都应该是 XML 属性编码的。浏览器的解析器会将其解释为 xml 属性并以这种方式对其进行解码。浏览器会将解码后的文本提供给 javascript 解释器,因此它应该是正确的 JavaScript 编码以防止安全泄漏。

这种双重编码不会导致无效的结果,因为浏览器也会双重解码这个文本(因为涉及到两个独立的解释器)。这是正确编码的示例。

string unsafeText = "Hello <unsafe> ');alert('xss');alert('";
string javaEncoded = AntiXss.JavascriptEncode(unsafeText, false);
ENCODED_STRING = AntiXss.XmlAttributeEncode(javaEncoded);

<input type="button" onclick="alert('[ENCODED_STRING]');"
    value="Click me" />

虽然双重编码是做到这一点的唯一正确方法,但我想指出,仅使用 JavaScript 编码通常会产生正确的结果。这里的约束是属性的文本放在引号之间。

JavaScript 编码使用与 HTML/XML 属性编码相同的白名单(空格字符除外)。它们之间的区别在于不安全字符的编码方式。Javascript 将它们编码为 \xXX 和 \uXXXX(如 \u01A3),而 XML 属性将它们编码为 &#XX; 和 &#XXXX; (例如 A3;)。使用 JavaScript 编码对文本进行编码时,只剩下两个字符将被 XML 属性编码器再次编码,即空格字符和反斜杠字符。这两个字符只有在属性的文本没有被引号括起来时才会出现问题。

但是请注意,在这种情况下仅使用 XML 属性编码不会产生正确的结果。

于 2010-06-22T13:21:08.653 回答
2

在单独的<script>标签中安装 onclick 处理程序。

<input type="button" id="clickMeButton" value="Click me" />

...

<script type="text/javascript">
...
document.getElementById('clickMeButton').onclick = function () {
   alert([ENCODED STRING HERE using AntiXss.JavascriptEncode]);
}
...
</script>
于 2010-06-08T10:23:44.400 回答
2

也许您应该尝试使用 base64 编码。它不会在您的 html 中包含无效数据(只要将编码的字符串放在单引号中),您可以使用 javascript 对其进行解码。

于 2010-06-08T11:56:36.420 回答