在HTTP请求参数中,使用"&"符号可以连接不同的参数,如:
str=hello&id=1
开发人员通常不会考虑有重复参数的问题,因为它比较少见。但在HTTP请求中并未规定不可以传输多个相同的参数项,如:
str=hello&str=world&str=xxser
使用这段参数请求,执行结果如图10-24所示。
经过观察图10-24可以发现,PHP在取值时忽略了前面的str参数的值,只取了最后一项进行输出。
图10-24 相同参数名的取值
这就是HTTP参数污染,继续观察下面的例子。
HttpParServlet.java源码如下:
public class HttpParServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); String str = request.getParameter("str"); out.println(str); out.flush(); out.close(); } } |
这段代码的含义很简单,接收HTTP参数str的值,并且打印在页面上,访问页面http://www.xxser.com:9527/Jsp/HttpParServlet?str=hello&str=world&str=xxser,打印结果如图10-25所示。
图10-25 Servlet取值结果
经过观察图10-25可以发现,Servlet的取值中并未取最后一项,而是取了第一项参数的值作为打印结果,证明不同脚本的语言和环境,其取值是不同的。
国外的安全研究者wisec把各个不同脚本环境的执行结果整理成了一张表,如图10-26所示。
那么HTTP参数污染到底有何作用呢?HPP参数污染经常用来绕过一些Web应用防火墙。
简单地说,WAF在脚本还未接收到请求之前就开始对数据进行校验,如果未发现恶意代码,则交给脚本去处理,如果发现恶意代码,就进行拦截,不再交给脚本去处理。
图10-26 HTTP参数处理图
这样问题就出现了,如:某个WAF防火墙模板定义数据中不允许出现select关键字,WAF取值验证时可能会选择第一项参数值,而脚本取值与WAF则不同,这样就有可能绕过WAF的数据验证。请求如下:
PHP : News.php?id=1&id=select username,password from admin--
WAF 取ID值为1,而PHP取ID值为select username,password from admin--
Asp.net: news.aspx?id=1;&id=s&id=e&id=l&id=e&id=c& id=t
而Asp.net将会把多个相同参数项的值连接在一起,这样使用HTTP参数污染就极有可能绕过某些WAF防火墙。
本文选自《Web安全深度剖析》第十章,本站经电子工业出版社和作者的授权。
版权声明:51Testing软件测试网获电子工业出版社和作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责任。