我有一段JavaScript字符串,来自不受信任的来源,嵌入在onclick标记内部,我不确定编码此字符串的正确方法是什么。以下是HTML的简化:
<input type="button" onclick="alert([ENCODED STRING HERE]);"
value="Click me" />
我使用包含几种编码方法的Microsoft AntiXss library。该文本嵌入在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。
答案 0 :(得分: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属性将它们编码为&amp; #XX;和&amp; #XXXX; (例如&amp;#01A3;)。使用JavaScript编码对文本进行编码时,只剩下两个字符,将由XML属性编码器再次编码,即空格字符和反斜杠字符。当属性的文本没有包含在引号之间时,这两个字符只会形成问题。
但请注意,在此方案中仅使用XML属性编码不会产生正确的结果。
答案 1 :(得分:2)
将onclick处理程序安装在单独的<script>
标记中。
<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>
答案 2 :(得分:2)
也许你应该尝试base64编码。它不会在你的html中包含无效数据(只要你将编码的字符串放在单引号中),你就可以用javascript解码它。