问题

在《白帽子讲Web安全》第三章的 3.3.3.2只需一种编码吗 中有下面一段话:

看看下面这个例子:

<body>
<a href=# onclick="alert('$var');">test</a>
</body>

如果用户输入

$var = htmlencode("');alert('2");

在对变量$var进行htmlencode后,渲染的结果是

<body>
<a href=# onclick="alert('&#x27;&#x29;&#x3b;alert&#x28;&#x27;2');" >test</a>
</body>

对浏览器来说,htmlparser会优先于JavaScript Parser执行,所以解析过程是,被HtmlEncode的字符先被解码,然后执行JavaScript事件。

<body>
<a href=# onclick="alert('');alert('2');">test</a>
</body>

这里的 $var = htmlencode("');alert('2"); 刚开始没有看懂。之后放在vscode中就看懂了。

原因

如图:

$var=htmlencode("');alert('2"); 的个人理解

这个函数是对双引号中的特殊符号进行了编码。也就是对');'进行编码。

因此也就有了渲染结果中的&#x27;&#x29;&#x3b;&#x27;

用户真实的输入其实是');alert('2,在对其进行htmlencode后,渲染成了&#x27;&#x29;&#x3b;alert&#x28;&#x27;2,接着在浏览器中显示的时候,由于htmlparser会优先于JavaScript Parser执行,所以先被解码回初始输入,');alert('2,最终执行javascript事件。