路径遍历漏洞如何规避

wen 网络安全 28

本文目录导读:

路径遍历漏洞如何规避

  1. 严格的基础防范:禁止拼接用户输入到文件路径
  2. 输入验证与净化(Input Validation & Sanitization)
  3. 路径规范化与安全检查(Canonicalization)
  4. 使用安全的API库
  5. 部署环境配置(多层防御)
  6. 常见绕过手法与对应防御

路径遍历漏洞(Path Traversal)是一种常见的Web安全漏洞,攻击者通过操纵文件路径参数(如 ../../../etc/passwd)来访问或执行服务器上未授权的文件,要有效规避此类漏洞,需从输入验证文件系统操作隔离应用架构设计三个层面入手。

以下是具体的安全编码与配置策略:

严格的基础防范:禁止拼接用户输入到文件路径

最根本的防御:不要直接使用用户提供的字符串来构造文件路径,如果业务逻辑必须根据用户请求读取文件,请遵循以下原则。

输入验证与净化(Input Validation & Sanitization)

如果无法完全避免用户输入参与路径构建,必须进行严格的过滤:

  • 白名单校验(首选):如果允许访问的文件数量有限,使用白名单(如枚举允许的ID、文件名或路径片段),用户只能传入ID,后端映射到固定路径。

    # 危险做法
    file = open("downloads/" + user_input, "r")
    # 安全做法(白名单映射)
    allowed_files = {
        "1": "report_q1.pdf",
        "2": "report_q2.pdf"
    }
    file_name = allowed_files.get(user_input)
    if file_name:
        file = open("downloads/" + file_name, "r")
  • 拒绝危险字符:过滤或拒绝包含 、、%2e%2e%2f(URL编码)或 \0(空字节,用于绕过旧版语言扩展名检查)的输入。

  • 文件类型与后缀限制:明确允许的后缀列表(如 .pdf, .txt, .png),拒绝其他所有后缀。

路径规范化与安全检查(Canonicalization)

即使过滤了 ,攻击者可能使用长路径、绝对路径或符号链接进行绕过,必须对处理后的最终路径进行校验:

  • 解析真实路径:使用系统调用获取路径的“绝对、无符号链接”的真实路径(如 realpath(),或 Python 的 os.path.realpath())。

  • 限定基目录:检查解析后的真实路径是否以你期望的基目录开头。

    import os
    BASE_DIR = "/var/www/app/data"
    def safe_file_path(user_input):
        # 1. 构建安全路径(假设已过滤了危险字符)
        safe_input = os.path.basename(user_input)  # 只取文件名,去掉目录部分
        full_path = os.path.join(BASE_DIR, safe_input)
        # 2. 规范化路径
        real_path = os.path.realpath(full_path)
        # 3. 检查是否在基目录内
        if real_path.startswith(os.path.realpath(BASE_DIR)):
            return real_path
        else:
            return None

使用安全的API库

尽量避免直接操作文件系统,使用专为安全设计的库:

  • Java:使用 java.io.FilegetCanonicalPath() 方法并检查前缀,或使用 Spring 的 ResourceUtilsUrlResource
  • Node.js:避免使用 fs.readFileSync(userInput),结合 path.resolve() 并检查是否在项目根目录下。
  • .NET:使用 Path.GetFullPath() 并配合 Directory.GetCurrentDirectory() 验证。

部署环境配置(多层防御)

即使代码存在疏忽,以下配置可以显著增加攻击难度:

  • 最小权限原则:Web应用程序的运行用户(如 www-data, nginx)只应拥有读取必要目录(如 public/, uploads/)的权限,禁止访问系统目录(/etc/, /proc/, /var/log/)。
  • 禁用不必要的文件系统功能:在 Web 服务器(Nginx/Apache)配置中,禁止对 uploads 目录执行脚本,仅允许静态文件服务。
  • 使用隔离的存储服务:如果条件允许,不要将用户文件存储在本地磁盘,使用对象存储(AWS S3, MinIO)或单独的HTTP文件服务,这样,应用程序完全不需要直接操作本地文件系统路径。

常见绕过手法与对应防御

攻击手法 示例输入 防御策略
简单目录遍历 ../../../etc/passwd 过滤
URL编码 ..%252f..%252f..%252f(双重编码) 解码后再进行路径检测
16位Unicode编码 ..%c0%ae%c0%ae/(针对旧版IIS) 使用最新版本的运行时环境
绝对路径 /etc/passwd 检查路径是否以基目录开头(而非仅检查相对路径)
空字节注入 ../../../etc/passwd%00.png 使用强类型语言,避免使用C风格的字符串;对输入进行空字节截断检测
符号链接 /var/www/app/data/link_to_etc(用户上传一个符号链接文件) 使用 realpath() 解析最终路径

规避路径遍历漏洞最有效的方法是 “不信任用户输入,永远不要直接拼接路径”,具体落地上:

  1. 首选非路径方案:使用 ID、哈希等间接引用代替路径。
  2. 其次白名单:穷举允许访问的文件。
  3. 最后防御层:使用 realpath() + 前缀检查,并降低服务器运行权限。
  4. 持续测试:使用静态代码扫描工具(SAST)和渗透测试工具(如 Burp Suite)定期检测。

抱歉,评论功能暂时关闭!