目录穿越攻击如何防护

wen 网络安全 29

本文目录导读:

目录穿越攻击如何防护

  1. 避免用户直接控制文件路径(最安全)
  2. 输入验证与过滤(必须执行)
  3. 路径规范化与验证(防御层)
  4. 最小权限原则(系统级防御)
  5. 使用安全的文件处理函数
  6. 操作系统与Web服务器配置(环境加固)
  7. 编码与Unicode攻击防御
  8. 输出编码与异常处理
  9. 综合防护流程图(理想实践)

目录穿越攻击(Path Traversal,又称路径遍历攻击)是一种通过操纵文件路径变量来访问服务器上受限制文件或目录的攻击手段,攻击者通过使用等特殊字符,尝试跳出Web根目录,访问系统敏感文件(如/etc/passwd、配置文件或数据库文件)。

以下是针对目录穿越攻击的核心防护策略,按优先级排序:

避免用户直接控制文件路径(最安全)

  • 根本方法:不要使用用户输入(如表单、URL参数)来直接构造文件路径。
  • 替代方案
    • 使用固定的文件ID、索引号或哈希值,通过映射表查找实际路径(用户输入file_id=123,服务器根据映射表返回/uploads/123.pdf)。
    • 将文件存储在数据库中,通过ID检索,而不是通过文件系统路径。

输入验证与过滤(必须执行)

如果无法避免使用用户输入构造路径,必须进行严格的输入清洗:

  • 白名单校验:只允许特定的、预期内的字符(如字母、数字、下划线、连字符、点)。禁止包含、、、等路径分隔符。

    # 不佳实践(黑名单,容易被绕过)
    if "../" in user_input: reject()
    # 推荐实践(白名单)
    allowed = re.match(r'^[a-zA-Z0-9_\-\.]+$', user_input)
    if not allowed: reject()
  • 拒绝路径字符:明确拒绝包含、、、、空字节(%00)等字符的输入。

路径规范化与验证(防御层)

即使通过了输入过滤,仍需对最终路径进行规范化检查:

  • 获取绝对路径:使用编程语言提供的路径规范化函数(如realpath()Path::realpath()os.path.abspath()),将用户输入拼接后的路径转换为绝对路径。
  • 检查前缀:确认规范化后的路径必须以允许的根目录(如/var/www/uploads/)开头。
    $base = '/var/www/uploads/';
    $path = realpath($base . '/' . $userInput);
    if (strpos($path, $base) !== 0) {
        reject(); // 尝试逃逸出允许目录
    }

    注意realpath() 会将解析为实际目录,但如果文件不存在会返回false,需先判断文件是否存在。

最小权限原则(系统级防御)

  • Web服务器权限:确保Web服务器运行的用户(如www-data)只具备读取其需要服务的目录(如/var/www/html)的权限,绝对没有读取/etc//proc//home/等系统目录的权限。
  • 禁用不必要的功能:在Web框架或脚本中,禁用远程文件包含(RFI)功能,或将其关闭。
  • 限制文件扩展名:如果只允许读取图片,应强制只响应.jpg.png等后缀,并拒绝执行脚本文件。

使用安全的文件处理函数

  • 避免使用直接拼接字符串的函数,如 fopen($base . '/' . $input)
  • 使用框架或库提供的安全文件访问API(如Node.jspath.join() + path.resolve() + 前缀检查,或Pythonpathlib库)。
  • 对于静态文件,可以考虑使用httpdnginx的反向代理功能(如aliasroot),让Web服务器处理路径解析,避免应用层直接操作文件系统。

操作系统与Web服务器配置(环境加固)

  • Windows系统:确保驱动器号(C:)不能通过路径逃逸。
  • 禁用短文件名(Windows):禁用8.3短文件名生成,防止攻击者利用短文件名猜测路径。
  • 配置Web服务器
    • Apache: 禁用 FollowSymLinks 或开启 SymLinksIfOwnerMatch
    • Nginx: 确保 alias 指令使用正确,避免 location /img/ { alias /var/www/; } 这种可能被/img/../etc/利用的错误配置。

编码与Unicode攻击防御

  • 注意对%2e%2e%2f(URL编码的)或..%252f(双重编码)的防御。解码顺序应是:先进行完整的URL解码,再执行路径检查。
  • 注意UTF-8变体(如..%c0%ae%c0%ae/)或超长路径(Unicode等效字符),更好的方式是只接受ASCII安全字符(白名单)。

输出编码与异常处理

  • 不要泄露路径信息:发生错误时,不要返回“文件不存在”或具体路径(如/var/www/html/secret.conf),而应返回通用的“404 Not Found”或“403 Forbidden”。
  • 统一错误页面:防止攻击者通过对比错误信息来枚举文件是否存在。

综合防护流程图(理想实践)

用户输入 (?file=../../../etc/passwd)
    |
    v
[1. 白名单校验] -- 包含非法字符?--> 拒绝
    |
    v (通过)
[2. 路径拼接与规范化] (使用 realpath)
    |
    v
[3. 前缀检查] -- 是否以安全根目录开头?--> 拒绝
    |
    v (通过)
[4. 文件扩展名检查] -- 是否允许类型?--> 拒绝
    |
    v (通过)
[5. 操作系统权限控制] -- 文件可读?--> 拒绝
    |
    v (最终读取或返回404)
  • 永远不要信任用户输入
  • 白名单 > 黑名单:指定允许的字符和目录,而不是试图过滤掉所有危险的。
  • 深度防御:结合输入过滤路径规范化最小权限安全配置,多层防护更能有效抵御绕过技巧。

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