跳到正文
Træfɪk

请求路径

通过清理与过滤防范基于路径的攻击

Traefik 在处理传入的请求路径时实施多层安全防护。 其中包括清理路径以规范化潜在危险序列,以及过滤编码字符以防止利用 URL 编码实施攻击。 了解 Traefik 如何处理请求路径,对于维护安全的路由基础设施至关重要。

Traefik 如何处理请求路径

收到 HTTP 请求后,Traefik 会通过以下几个面向安全的阶段处理请求路径:

1. 编码字符过滤

Traefik 检查路径中是否存在潜在危险的编码字符;除非显式允许,否则会拒绝包含这些字符的请求。

以下编码字符默认允许使用:

编码字符 对应字符
%2f 或 %2F /(斜杠)
%5c 或 %5C \(反斜杠)
%00 NULL(空字符)
%3b 或 %3B ;(分号)
%25 %(百分号)
%3f 或 %3F ?(问号)
%23 #(井号)

2. 路径规范化

Traefik 会解码以百分号编码的非保留字符,以规范化请求路径, 因为这些字符与其未编码形式等价(参见 rfc3986#section-2.3); 同时将百分号编码中的字母转换为大写(参见 rfc3986#section-6.2.2.1)。

3. 路径清理

Traefik 通过从 URL 中移除 ..、. 和重复斜杠片段来清理请求路径, 防止常见攻击手段(参见 rfc3986#section-6.2.2.3)。

路径安全配置

Traefik 提供了两种主要的路径安全机制,它们相互配合以保护应用。

路径清理

路径清理默认启用,通过规范化请求路径帮助防止目录遍历攻击。 可以在入口点的 HTTP 配置部分设置它:

entryPoints:
  websecure:
    address: ":443"
    http:
      sanitizePath: true  # Default: true (recommended)
[entryPoints.websecure]
  address = ":443"

  [entryPoints.websecure.http]
    sanitizePath = true
--entryPoints.websecure.address=:443
--entryPoints.websecure.http.sanitizePath=true

清理行为:

  • ./foo/bar → /foo/bar(移除相对当前目录片段)
  • /foo/../bar → /bar(解析父目录遍历)
  • /foo/bar// → /foo/bar/(移除重复斜杠)
  • /./foo/../bar// → /bar/(组合上述全部规范化操作)

编码字符过滤

编码字符过滤通过拒绝潜在危险的 URL 编码字符,提供额外一层防护。 可以在入口点的 HTTP 配置部分设置它。

过滤发生在路径清理之前,可拦截使用编码绕过其他安全控制的攻击尝试。

所有编码字符过滤默认关闭(true 表示允许该编码字符)。

安全注意事项

当后端未完全遵循 RFC 3986,尤其是会解码请求路径中已编码的保留字符时, 建议将这些选项设为 false,以避免代理与后端对路径的理解不一致,并帮助防止路径遍历或其他绕过安全控制的恶意尝试。

entryPoints:
  websecure:
    address: ":443"
    http:
      encodedCharacters:
        allowEncodedSlash: false          # %2F - Default: true
        allowEncodedBackSlash: false      # %5C - Default: true
        allowEncodedNullCharacter: false  # %00 - Default: true
        allowEncodedSemicolon: false      # %3B - Default: true
        allowEncodedPercent: false        # %25 - Default: true
        allowEncodedQuestionMark: false   # %3F - Default: true
        allowEncodedHash: false           # %23 - Default: true
[entryPoints.websecure]
  address = ":443"

  [entryPoints.websecure.http.encodedCharacters]
    allowEncodedSlash = false
    allowEncodedBackSlash = false
    allowEncodedNullCharacter = false
    allowEncodedSemicolon = false
    allowEncodedPercent = false
    allowEncodedQuestionMark = false
    allowEncodedHash = false
--entryPoints.websecure.address=:443
--entryPoints.websecure.http.encodedCharacters.allowEncodedSlash=false
--entryPoints.websecure.http.encodedCharacters.allowEncodedBackSlash=false
--entryPoints.websecure.http.encodedCharacters.allowEncodedNullCharacter=false
--entryPoints.websecure.http.encodedCharacters.allowEncodedSemicolon=false
--entryPoints.websecure.http.encodedCharacters.allowEncodedPercent=false
--entryPoints.websecure.http.encodedCharacters.allowEncodedQuestionMark=false
--entryPoints.websecure.http.encodedCharacters.allowEncodedHash=false

按路由过滤编码字符

如果需要为不同路由分别配置编码字符过滤,可以使用 EncodedCharacters 中间件。 具体实现方法与配置选项请参阅 EncodedCharacter 中间件文档。


版权所有 © 头文件软件工作室

文档由 HeadFile Studio 翻译。

Traefik v3.7 中文快照 · 原文版权归 Traefik Labs 及贡献者所有 · MIT 许可证