目录遍历安全问题
Posted
技术标签:
【中文标题】目录遍历安全问题【英文标题】:Directory traversal security issue 【发布时间】:2011-06-01 18:05:46 【问题描述】:我有一个 Java webapp,它容易受到通过 URL 编码的目录横向(又名路径横向)攻击。认证后:
如果我点击 http://localhost:8080/Web/WEB-INF/web.xml,我会得到 404(这很好) 如果我点击 http://localhost:8080/Web/%c0%ae/WEB-INF/web.xml ,我可以读取文件(这显然不是很好)根据 Servlet 规范,WEB-INF 文件夹不应该被公开访问,但在这种情况下它可以工作。 我将 Websphere 5.1 与 Java 1.4、Spring Security 2.0.5 和 Struts 1.3 一起使用。 从我读到的,它似乎与编码有关,%c0%ae 是 '.' (点)在 UTF-8 中。
我在另一个运行在不同环境(Tomcat 6 with Java 7、Spring Security 3 和 Spring MVC)中的不同 webapp 上尝试了同样的事情,但我无法重现该问题。第二个 webapp 有一个过滤器来强制以 UTF-8 (org.springframework.web.filter.CharacterEncodingFilter
) 对页面进行编码,所以我在第一个 webapp 上尝试了相同的配置,但它没有成功。
有什么想法吗?
谢谢。
【问题讨论】:
有没有什么方法可以更新系统上的 Spring 和/或 Java 版本?听起来像 CVE-2010-3700 很遗憾,这不是我能控制的。 那我建议限量发行。这是这个版本的一个已知问题,如果客户不升级到新版本,他将不得不忍受它给他带来的麻烦。我知道不是很有用。抱歉,也许其他人会想出一些办法。 我可以看到这确实是一个已知问题。谢谢,爱德华。 运行具有许多已发布漏洞的旧版本软件可能不是最好的主意。 【参考方案1】:我将回答我自己的问题。 因此,由于我拥有的选项有限,我最终要做的是在 Spring Security 配置文件中添加一个安全规则,例如
<sec:intercept-url pattern="/**/WEB-INF/**" access="no-access"/>
它将对 WEB-INF 的访问限制为“禁止访问”角色,实际上这不是一个角色。这会阻止对所有用户的访问。这并不理想,但在升级之前可以解决问题。
【讨论】:
您可能还应该为 META-INF 添加一条规则。 您可以在 META-INF 中定义安全规则吗?这是如何工作的? 不,我的意思是你应该使用相同类型的规则来阻止对 META-INF 的访问,而不仅仅是 WEB-INF。【参考方案2】:您可以通过另一个网络服务器/应用服务器或Web application firewalls 代理它们,在它们到达 Websphere 之前修复或拒绝这些请求。另一个 Java 应用程序服务器或类似 nginx 或 Varnish 的东西都可以解决问题。
当然,真正的解决方案是升级。这只是一个创可贴,可以被颠覆。这确实是“修复”安全问题的错误方法。
【讨论】:
很遗憾,我没有添加此类组件的选项。【参考方案3】:过滤器更改请求正文的字符编码,而不是 URL。
要在tomcat中设置URL编码,需要在server.xml的
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />
【讨论】:
谢谢 Maurice,但是在 Websphere 中有没有等价物?【参考方案4】:如果您无法升级(古老的 WebSphere + Java 1.4,哎呀!),一种可能的解决方法(实际上更像是一种hackaround)是编写一个简单的过滤器,映射到每个请求,进行正确的字符集转换和拒绝无效请求。
我相信通过一些挖掘,您可以找到一个检查您可能没有想到的事情的实现。
当然,这仍然会留下 8 年的其他安全(更不用说生产力)问题。
哎呀
没注意到没注意到问题的年龄。
【讨论】:
您如何确定请求无效?您是否必须手动更新此类请求的列表?【参考方案5】:这是我的实现
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author davidandrade
*/
public class RestrictURL implements Filter
private FilterConfig fcgConfFiltr_t;
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(RestrictURL.class.getName());
@Override
public void init(FilterConfig filterConfig) throws ServletException
fcgConfFiltr_t = filterConfig;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String strUrlPetici_t = req.getRequestURL().toString();
String strUrlBase___t = strUrlPetici_t.substring(0, strUrlPetici_t.indexOf(fcgConfFiltr_t.getServletContext().getContextPath()) + fcgConfFiltr_t.getServletContext().getContextPath().length());
try
res.addHeader("X-Frame-Options", "SAMEORIGIN");
log.info("URL Req: " + strUrlPetici_t);
if (strUrlPetici_t.toLowerCase().contains("%co") || strUrlPetici_t.toLowerCase().contains("%ae"))
sendErrorRedirect(req, res, "/404.jsf", new Exception("DirectoryTransversalRequired"));
else
try
fcgConfFiltr_t.getServletContext().getRequestDispatcher(strUrlPetici_t).forward(request, response);
catch (IllegalArgumentException e)
chain.doFilter(request, response);
catch (Exception e)
log.error("", e);
sendErrorRedirect(req, res, "/404.jsf", e);
protected void sendErrorRedirect(HttpServletRequest request, HttpServletResponse response, String errorPageURL, Throwable e) throws ServletException, IOException
request.setAttribute("exception", e);
fcgConfFiltr_t.getServletContext().getRequestDispatcher(errorPageURL).forward(request, response);
@Override
public void destroy()
fcgConfFiltr_t = null;
并将过滤器添加到我的 web.xml
<filter>
<filter-name>DirectoryTransversalFilter</filter-name>
<filter-class>com.sec.RestrictURL</filter-class> <!-- mandatory -->
</filter>
<filter-mapping>
<filter-name>DirectoryTransversalFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
【讨论】:
以上是关于目录遍历安全问题的主要内容,如果未能解决你的问题,请参考以下文章