如何在 XML 属性内对 JavaScript 文本进行编码?

发布于 2024-09-04 21:42:11 字数 1022 浏览 3 评论 0原文

我有一段 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 编码似乎也合适。

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


UPDATE: The workaround I currently use is by using XmlAttributeEncode on this text and put this inside a custom attribute in the tag. After that I use some JavaScript to read it from this tag. It basically looks like this:

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

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

I have a piece of JavaScript string, coming from an untrusted source, embedded inside of an onclick tag and I'm not sure what the correct way of encoding this string is. Here is a simplification of the HTML:

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

I use the Microsoft AntiXss library which contains several methods to encode with. The text is embedded in a HTML / XML attribute, so XML attribute encoding, using the AntiXss.XmlAttributeEncode method seems appropriate. However, it is also a piece of JavaScript. Therefore JavaScript encoding using the the AntiXss.JavascriptEncode method seems appropriate too.

Which one should I choose in such a way that I don’t expose a security leak, while allowing the text to be displayed correctly?


UPDATE:
The workaround I currently use is by using XmlAttributeEncode on this text and put this inside a custom attribute in the tag. After that I use some JavaScript to read it from this tag. It basically looks like this:

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

While this works perfectly and solves the problem, I'm still very curious about how to correctly encode JavaScript inside an XML attribute.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

奶气 2024-09-11 21:42:11

正确的答案是对文本进行双重编码。首先使用 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 属性编码不会产生正确的结果。

The correct answer is to double encode the text. First with JavascriptEncode and next with XmlAttributeEncode. The rationale behind this is that everything within a xml/html attribute should be XML attribute encoded. The parser of the browser will interpret this as an xml attribute and decode it that way. The browser will supply this decoded text to the javascript interpreter and it should therefore be JavaScript encoded properly to prevent a security leak.

This double encoding will not result invalid results, because the browser will also double decode this text (because two separate interpreters are involved). Here is an example of the correct encoding.

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" />

While double encoding is the only correct way to do this, I like to note that using only JavaScript encoding will usually yield correct result. The constraint here is that the attribute's text is put between quotes.

JavaScript encoding uses the same white list (except for the space character) as HTML/XML attribute encoding. Difference between them is how unsafe characters are encoded. Javascript encodes them as \xXX and \uXXXX (such as \u01A3), while XML attribute encodes them as &#XX; and &#XXXX; (such as A3;). When encoding text with JavaScript encoding, there are only two characters left that will be encoded again by the XML attribute encoder, namely the space character and the backslash character. Those two characters would only be form a problem when the attribute’s text isn’t wrapped between quotes.

Note however that only using XML attribute encoding in this scenario will NOT yield correct result.

游魂 2024-09-11 21:42:11

在单独的

<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>

Install the onclick handler in a separate <script> tag.

<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>
鸢与 2024-09-11 21:42:11

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

Maybe you should try a base64 encoding. It won't contain invalid data in your html (as soon as you place the encoded string in single quotes) and you can decode it with javascript.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文