当前位置: 首页 > news >正文

聊聊directory traversal attack

本文主要研究一下directory traversal attack及其防范

directory traversal attack

又称Path Traversal attack,即目录遍历攻击,旨在访问web服务器根目录外的文件/目录。通过是通过url或变量里头传递"../"来进行目录遍历。

通过url

比如

http://some_site.com.br/../../../../some dir/some file 

或者

http://some_site.com.br/../../../../etc/shadow 

通过变量名

通常是在文件下载接口中,比如

http://some_site.com.br/get-files?file=/etc/passwd 

或者

http://some_site.com.br/get-files?file=../../../../some dir/some file 

防范

针对url

spring security提供了DefaultHttpFirewall来进行处理,是为了防止一些web框架没有遵循servlet规范而进行的防范。
spring-security-web-4.2.3.RELEASE-sources.jar!/org/springframework/security/web/firewall/DefaultHttpFirewall.java

/**
 * Default implementation which wraps requests in order to provide consistent
 * values of the {@code servletPath} and {@code pathInfo}, which do not contain
 * path parameters (as defined in
 * <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>). Different
 * servlet containers interpret the servlet spec differently as to how path
 * parameters are treated and it is possible they might be added in order to
 * bypass particular security constraints. When using this implementation, they
 * will be removed for all requests as the request passes through the security
 * filter chain. Note that this means that any segments in the decoded path
 * which contain a semi-colon, will have the part following the semi-colon
 * removed for request matching. Your application should not contain any valid
 * paths which contain semi-colons.
 * <p>
 * If any un-normalized paths are found (containing directory-traversal
 * character sequences), the request will be rejected immediately. Most
 * containers normalize the paths before performing the servlet-mapping, but
 * again this is not guaranteed by the servlet spec.
 *
 * @author Luke Taylor
 */
public class DefaultHttpFirewall implements HttpFirewall {
    private boolean allowUrlEncodedSlash;

    @Override
    public FirewalledRequest getFirewalledRequest(HttpServletRequest request) throws RequestRejectedException {
        FirewalledRequest fwr = new RequestWrapper(request);

        if (!isNormalized(fwr.getServletPath()) || !isNormalized(fwr.getPathInfo())) {
            throw new RequestRejectedException("Un-normalized paths are not supported: " + fwr.getServletPath()
                    + (fwr.getPathInfo() != null ? fwr.getPathInfo() : ""));
        }

        String requestURI = fwr.getRequestURI();
        if (containsInvalidUrlEncodedSlash(requestURI)) {
            throw new RequestRejectedException("The requestURI cannot contain encoded slash. Got " + requestURI);
        }

        return fwr;
    }

    @Override
    public HttpServletResponse getFirewalledResponse(HttpServletResponse response) {
        return new FirewalledResponse(response);
    }

    /**
     * <p>
     * Sets if the application should allow a URL encoded slash character.
     * </p>
     * <p>
     * If true (default is false), a URL encoded slash will be allowed in the
     * URL. Allowing encoded slashes can cause security vulnerabilities in some
     * situations depending on how the container constructs the
     * HttpServletRequest.
     * </p>
     *
     * @param allowUrlEncodedSlash
     *            the new value (default false)
     */
    public void setAllowUrlEncodedSlash(boolean allowUrlEncodedSlash) {
        this.allowUrlEncodedSlash = allowUrlEncodedSlash;
    }

    private boolean containsInvalidUrlEncodedSlash(String uri) {
        if (this.allowUrlEncodedSlash || uri == null) {
            return false;
        }

        if (uri.contains("%2f") || uri.contains("%2F")) {
            return true;
        }

        return false;
    }

    /**
     * Checks whether a path is normalized (doesn't contain path traversal
     * sequences like "./", "/../" or "/.")
     *
     * @param path
     *            the path to test
     * @return true if the path doesn't contain any path-traversal character
     *         sequences.
     */
    private boolean isNormalized(String path) {
        if (path == null) {
            return true;
        }

        for (int j = path.length(); j > 0;) {
            int i = path.lastIndexOf('/', j - 1);
            int gap = j - i;

            if (gap == 2 && path.charAt(i + 1) == '.') {
                // ".", "/./" or "/."
                return false;
            } else if (gap == 3 && path.charAt(i + 1) == '.' && path.charAt(i + 2) == '.') {
                return false;
            }

            j = i;
        }

        return true;
    }

}
这里会对url进行判断

通过变量

这种框架没有内置进行判断,需要自己在开发应用服务的时候额外关注。这里谈谈几种防范方法。

  • 对变量名进行过滤
final Pattern INVALID_PATH_PATTERN = Pattern.compile("(\\.\\.\\/|\\.\\.\\\\)");
if(INVALID_PATH_PATTERN.matcher(path).find()){
    throw new BadRequestException("invalid path");
}
  • 利用absolutePath与canonicalPath
absolutePath不会处理../之类的,而canonicalPath会翻译../,判断两者是否相等即可判断是否有../
        if (!file.getAbsolutePath().equals(file.getCanonicalPath())) {
            throw new BadRequestException("invalid path");
        }

小结

在编写文件下载服务的时候,需要特别关注directory traversal attack。通常url层面的web框架会帮你防范,但是变量层面的,则需要自己开发额外注意。

doc

  • Path Traversal
  • Directory traversal attack

相关文章:

  • 如何使用C#关键字const,readonly,static
  • 零元学Expression Blend 4 - Chapter 10 用实例了解布局容器系列-「StackPanel」
  • 使用VS2013分析DMP文件
  • jsp 引用css/js文件返回html网页问题
  • 用户管理 之 Linux 用户管理工具介绍
  • 妙用this关键字
  • 南宁seo教程:巧用页面更新机制保障快照更新
  • JVM原理讲解和调优
  • Microsoft's Office - ATC Shanghai
  • memcached与redis区别
  • openstack-6:安装keystone、memcache和注册keystone
  • SpringBoot 对Future模式的支持
  • 20.4. tex2page
  • 在python中使用zookeeper管理你的应用集群
  • Docker启动/停止/进入容器的常见操作
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 分享一款快速APP功能测试工具
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • AngularJS指令开发(1)——参数详解
  • Apache Zeppelin在Apache Trafodion上的可视化
  • IDEA 插件开发入门教程
  • Java 最常见的 200+ 面试题:面试必备
  • Laravel Telescope:优雅的应用调试工具
  • mockjs让前端开发独立于后端
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Selenium实战教程系列(二)---元素定位
  • vuex 笔记整理
  • Vue小说阅读器(仿追书神器)
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 大快搜索数据爬虫技术实例安装教学篇
  • 码农张的Bug人生 - 初来乍到
  • 如何设计一个微型分布式架构?
  • 异步
  • 正则学习笔记
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • ​2020 年大前端技术趋势解读
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​卜东波研究员:高观点下的少儿计算思维
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • #我与Java虚拟机的故事#连载15:完整阅读的第一本技术书籍
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (13):Silverlight 2 数据与通信之WebRequest
  • (差分)胡桃爱原石
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (正则)提取页面里的img标签
  • ***检测工具之RKHunter AIDE
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .net core 源码_ASP.NET Core之Identity源码学习
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .net2005怎么读string形的xml,不是xml文件。
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • .NET运行机制
  • @TableId注解详细介绍 mybaits 实体类主键注解