介绍

在《白帽子讲web安全》的第三章的3.3.6 防御DOM Based XSS中,有下面这段话:

那是不是因为对“$var”用错了编码函数呢?如果改成HtmlEncode会怎么样?继续看下面这个例子:

<script>
    var x = "1&#x22;&#x29;&#x3b;alert&#x28;2&#x29;&#x3b;&#x2f;&#x2f;&#x22; ";
    document.write("<a href=# onclick = 'alert(\"" + x + "\")' > test</a > ");
</script>

服务器把变量HtmlEncode后再输出到<script>中,然后变量x作为onclick事件的一个函数参数被document.write到了HTML页面里。

问题

在上面代码的第三行:onclick = 'alert(\"" + x + "\")' 这句代码看得很迷糊,仔细分析后终于看懂,记录一下。

解决

alert(\"" + x + "\")不可以分开看,它是跟document.write连在一起的。

document.write("<a href=# onclick = 'alert(\"" + x + "\")' > test</a > ");

直接看的话看不出分割,用不同颜色标识一下:

理解 白帽子讲web安全 'alert(\"" + x + "\")'

如图可以看出,该write的参数有三个字符串。再用张图标示一下分割字符串的双引号:

理解 白帽子讲web安全 'alert(\"" + x + "\")'

就是上面显示的这两对双引号。


首先看一下第一部分,蓝色双引号之间的部分:

<a href=# onclick = 'alert(\"

由于\"代表着转义,所以相当于

<a href=# onclick = 'alert("

再看第二部分,也就是x的值

1&#x22;&#x29;&#x3b;alert&#x28;2&#x29;&#x3b;&#x2f;&#x2f;&#x22; 

将html实体还原成字符:

1");alert(2);//"

接着看第三部分,红色双引号之间的部分:

\")' > test</a >

同样由于\"代表着转义,所以相当于

 ")' > test</a >

最后将它们拼在一起,就是:

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

//注释掉了后面的双引号,所以等同于

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

分析结束。