j2ee 外部参数引用(URL)实现转向(forward)功能造成安全目录访问绕过的安全问题!
//最近发的一个漏洞,让我产生一个疑惑。今天刚好实现了一下URL跳转,发现问题产生的原因其实很简单。
首先看这一段Servlet的URL跳转实现代码(jsp及框架部分的举例省略,你懂的!):
String path=request.getParameter("path"); RequestDispatcher rd = request.getRequestDispatcher(path); rd.forward(request, response);
附带Servlet获得转向(转发)RequestDispatcher对象两种方式:
javax.servlet.http.HttpServletRequest.RequestDispatcher() javax.servlet.RequestDispatcher.getRequestDispatcher()
我们可以用实现带参数的跳转功能,如图:
看看转向的描述:forward重定向是在容器内部实现的同一个Web应用程序的重定向,所以forward方法只能重定向到同一个Web应用程序中的一个资源。
注意到它是在服务器端同一个应用(本应用)进行重定向。所以即使有外部任意参数输入,并不能实现一个严格意义的所谓“文件包含”漏洞,因为Servlet是有安全限制的,如图:
//ps:这里不是说操作系统中文件路径该xxx.jsp实际不存在啊!而是Servlet只在本应用中找不到该文件路径,造成异常java.lang.NullPointerException
但是它能够这样,如图(这是WEB-INF目录的第二次安全问题了,受保护的东西都是“惹眼”的!):
再说原因,再看WEB-INF目录介绍:http://baike.baidu.com/view/1745468.htm
WEB-INF是Java的WEB应用的安全目录。所谓安全就是客户端无法访问,只有服务端可以访问的目录。
注意到:“只有服务端可以访问的目录。”然后匹配一下上面“转向”的描述,forward访问转发是在服务器端完成的,所以客户端浏览器就能够通过http方式访问到WEB-INF安全目录(所以如果没有WEB-INF目录,基本是没有任何危害的!),就这么简单!
危害参考(同等危害):j2ee分层结构在某些场景下的缺陷及相关漏洞的详细描述后的定义
(但两个问题产生的原因是有本质区别的,前者是多个WEB服务器安全标准不一致使用不当导致的安全问题;此处是自身机制引用不当造成的安全问题!)
目测的实际案例:WooYun: 百度某应用任意文件读取问题!
(当时,觉得疑惑是因为在j2ee开发中,结合框架的使用习惯,很少会用一个外部参数去实现URL转向的(当然我发现的实际案例中也很多确实是用外部参数进行转向!),主要自己也没这么做过!)
解决方法:
//所以在使用j2ee实现外部参数URL跳转时多注意,可能很容易发生这个问题!
response.sendRedirect(request.getContextPath()+path);
尽量使用response重定向。
或者限制参数中的WEB-INF路径!
(根据实际的业务逻辑情况给出处理吧!)。
/*
那为什么response重定向跳转不导致该安全问题了?
因为:sendRedirect方法是告诉客户端重定向到任意的URL,浏览器再去访问这个地址,转向并不是在服务器端。(详细:请查看Servlet对象转向与重定向的区别。)!
*/
附带在实际开发中另一个功能实现中可能大量使用的demo,<iframe>标签资源文件包含:
1.jsp文件源代码部分:
<iframe height="100%" width="100%" src="Url?path=<%=request.getParameter("path")%>" frameborder="0" scrolling="no" ></iframe>