编码绕过问题
在bwapp上尝试xss注入时,在level3层次上,后台用了htmlspecialchars函数编码转义,没有办法绕过。网上搜索后,给出的结论是,函数对&,',",<,>进行了转义,其本身没法绕过,但是视它所处的环境来定。比方说,
<html>
<body>
<p id="1">hello</p>
<script>
document.getElementById("1").innerHTML = x;
</script>
</body>
</html>
注意这个x变量,它首先是在script环境下,然后通过改变dom结构,又输出到了html环境中,所以它会先被js解码,然后又被html解码。如果我们构造一个js编码后的攻击payload,那么它不含&,',",<,>,所以可以绕过htmlspecialchars函数,当它解析之后,加入到html中之后,就又成为有攻击性的代码得以执行。
这个问题得以理解之后,我在看道哥的《白帽子讲web安全》一书中,看到了关于DOM型xss的内容,它不按攻击代码是否存储于服务器来划分,而是指通过改变DOM结构来达到攻击的这一类的xss。就上面的例子来说,script中的内容输出到html中,就正好形成了一次xss攻击。
这样就又引来了新的思考,第一,浏览器解析过程;第二,浏览器解码顺序。
浏览器解析过程
浏览器的解析过程,关于这个问题,可以参考how browsers work,它的译文How browsers work,觉得复杂的可以参考HTML页面加载和解析流程详细介绍。总结下来,就是从头开始加载,遇见<script>标签时js参与进来进行dom树的构建,遇见css样式文件加载进行渲染,这个过程是同步完成的,中间会有交叉,最终完成rendering tree的渲染。这个过程很复杂,我非常纠结于解码的过程发生在构建完rendering tree树之后还是同时进行的,然后js解码和html解码的顺序。
解码顺序
文章编码与解码 -- 浏览器做了什么谈到html实体解码在DOM树构建之后,他也给出了证明,因为试图构造
<img src="http://www.example.com">
这样的攻击是无效的,因为它破坏了dom树的构建,而HTML 解码,是在DOM树结构OK,对节点内容解析的时候,会进行转码。
那么html解码和js解码的顺序是怎么样的,
-
在遇到<script>,<style>标签时,解码会交由js解码完成。
-
在遇到类似于
<img src=# onerror="alert(1)" />
这样既在html环境内,又会触发js解释器的情况下(onclick,onbeforeunload等),会先进行html解码,在触发onerror时又会对js进行解码。
所以,在进行防止xss攻击时,要注意数据的流向经过哪些环境,在每一个环境下都需要进行一次处理。
就以开头的例子来说,变量首先是在js环境中,再到html环境中,顺序是js解码,html解码,那么我们后台在进行处理的时候,就需要先对变量做一次html编码,再做一次js编码。