内联 HTML javascript 事件将转义引号解释为结束引号

inline HTML javascript event intreprets escaped quote as a closing quote

内联 HTML js 事件是否不关心转义引号?

$xss = addslashes("'><script>alert(/XSS/.source)</script>");
echo "<a href='/deleteaction.php' onclick='javascript:if(!confirm(\"{$xss}\")) return false'>Delete</a>";

制作HTML:

<a href='/deleteaction.php' onclick='javascript:if(!confirm("\'>
<script>alert(/XSS/.source)</script>
")) return false'>Delete</a>

编辑:所以这实际上执行了脚本。我认为它会在确认框中生成这样的字符串:

'><script>alert(/XSS/.source)</script>

但第一个单引号被解释为 onclick 事件的结束引号。所以我的问题是为什么它被解释为结束引号,即使它前面有反斜杠?

这是正确的 $xss 值。你在最后漏掉了一个单引号。

$xss = addslashes("'><script>alert(/XSS/.source)</script>'");

已编辑

我们不能在代码中直接使用 < 和 > 标签,因为它们是为 html 标签保留的标准 html 标签,而是使用 html 实体

$xss = addslashes("'&gt;&lt;script&gt;alert(/XSS/.source)&lt;/script&gt;'");

希望对您有所帮助。

我从http://www.jibbering.com/faq/faq_notes/script_tags.html

找到了答案

The values of event handling attributes will almost certainly need to be quoted because it is nearly impossible to write a javascript statement that only uses the characters allowed in an unquoted attribute value. And quoting can get quite involved in attribute values because they need to be quoted in the HTML source so whatever type of quote marks are used in the HTML cannot be used within the javascript code provided as the value because the HTML parser would take them as ending the string for the attribute value. While javascript string literals allow the use of double quotes or single quotes as delimiters and allow the type of quote not used as the delimiter to appear within the string literal unescaped.

So, given a desire to assign the string "don't do that" to an element's value property in an onclick event, because of the single quote appearing in the string itself the attribute value onclick='this.value = "don't do that";' will not work because the HTML parser will take the second single quote as ending the attribute value. It will not work to simply escape the single quote as onclick='this.value = "don\'t do that";' because the HTML parser doesn't know anything about javascript escapes and still sees the second single quote in the middle of the javascript string.

In this case escaping the single quote and reversing the quoting between the HTML and the javascript onclick="this.value = 'don\'t do that';" or using a javascript hex escape (which the HTML parser will not see as a quote) onclick='this.value = "don\x27t do that";' would solve the problem. But quotes in event handling attribute strings that define code that uses string literals often needs to be thought about.

这是因为浏览器的 HTML 解析器在 JavaScript 解析器之前运行。

在 HTML 中,\' 不被识别为单引号字符,它被识别为字面上的反斜杠后跟单引号。

单引号的正确 HTML 是 &#x27;(或十进制的 &#039;)。

要修复它,您应该使用 htmlentities 以及 addslashes

例如

$xss = addslashes(htmlentities("'><script>alert(/XSS/.source)</script>", ENT_QUOTES));

这将输出:

<a href='/deleteaction.php' onclick='javascript:if(!confirm("&#039;&gt;&lt;script&gt;alert(/XSS/.source)&lt;/script&gt;")) return false'>Delete</a>

确认显示的正确编码是:

请注意,这仅适用于可以包含脚本的 HTML 属性,不适用于 <script> 标签内的内容,因为该内容不是 运行 通过 HTML 解析器(HTML 解析器只查找最终的 </script> 直到它恢复 HTML 处理)。

请注意,如果字符串包含 \ 个字符,我们也需要 addslashes

一种不那么混乱的编码方式是遵循 Rule #3 of the OWASP XSS (Cross Site Scripting) Prevention Cheat Sheet:

Except for alphanumeric characters, escape all characters less than 256 with the \xHH format to prevent switching out of the data value into the script context or into another attribute.

因此,我们只是 JavaScript 十六进制实体编码,而不是同时对斜杠和 HTML 进行编码。据我所知,PHP 不提供开箱即用的功能(尽管如果我错了请纠正我)。

这也处理了属性是单引号、双引号或未引号的情况(因为 space 被转换为 \x20)。