← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-48020 · CWE-863 · Disclosed 2026-06-05

Traefik StripPrefix route-level authentication bypass via path normalization

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a side door created by a routing shortcut, not a skeleton key for every Traefik box

CVE-2026-48020 affects Traefik when a public router uses PathPrefix together with the StripPrefix middleware, and a separate router protects sensitive paths like /admin or /internal/config with authentication. In vulnerable builds (<= v2.11.46, <= v3.6.17, <= v3.7.1), a request such as /api../admin or /api%2e%2e/admin can match the public route first, then be normalized after prefix stripping into a protected backend path. The result is route-level auth bypass, not a generic Traefik takeover.

The vendor/CNA tagged this High with CVSS v4 7.8, and the underlying bug is real. Operationally, though, that overstates fleet-wide urgency: exploitation requires a fairly specific routing pattern, internet reachability, and a backend path that becomes sensitive only after normalization. For a 10,000-host estate, this is a configuration-dependent edge-proxy bug with potentially serious local impact but a meaningfully narrower exposed population than a universal unauthenticated RCE.

"Real auth bypass, but only if you built the exact PathPrefix+StripPrefix trap yourself"
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find an exposed Traefik edge with the risky route design

The attacker needs an internet-facing Traefik instance that exposes a public route using PathPrefix and StripPrefix, while a separate route protects backend paths with auth. This is the real gate: the bug is not exploitable just because Traefik is present; the routing topology has to line up.
Conditions required:
  • Traefik is reachable from the attacker's network position
  • A public router uses PathPrefix(...) with StripPrefix
  • A separate authenticated/protected route exists for backend paths
Where this breaks in practice:
  • Many deployments use host-based routing only and never use this pattern
  • A lot of enterprise admin paths are not exposed through the same public entrypoint
  • Internal-only Traefik deployments are already outside unauthenticated internet reach
Detection/coverage: Version scanners can find vulnerable releases, but they cannot tell whether the risky routing pattern exists. You need config-aware review of file-provider configs, Kubernetes CRDs, Helm values, Docker labels, or Compose manifests.
STEP 02

Send a normalization payload

Using a basic HTTP client like curl, the attacker sends a crafted path such as /api../admin or /api%2e%2e/admin. At routing time, the public PathPrefix route matches; after StripPrefix, path normalization changes the effective backend request into /admin or another protected path.
Conditions required:
  • The public route prefix can be abused with .. or %2e%2e segments
  • Normalization occurs after prefix stripping in the vulnerable build
Where this breaks in practice:
  • Some upstream WAFs, CDNs, or path-normalization filters may reject obvious traversal-style payloads
  • Custom route patterns like PathRegexp(^/api(/|$)) or PathPrefix(/api/) break the bypass
Detection/coverage: Web logs can show suspicious paths containing /../, /.., or percent-encoded dot segments near public prefixes. Default vuln scanners are unlikely to safely validate this without custom checks.
STEP 03

Bypass the protected router boundary

Because the request was admitted through the public router, the auth middleware on the protected router is never enforced for that transaction. Traefik forwards a normalized protected path to the backend even though the caller never satisfied the intended auth boundary.
Conditions required:
  • The protected resource is reachable on the same backend/service path after normalization
  • Authentication lives at the route boundary rather than solely inside the backend app
Where this breaks in practice:
  • If the backend performs its own strong auth, the proxy bypass alone may not yield sensitive access
  • If the protected endpoint is absent, the attack falls flat into 404s
Detection/coverage: Look for requests where unauthenticated sessions hit admin or internal paths via public prefixes, especially where the logged inbound path differs materially from the backend-observed path.
STEP 04

Land impact on the backend, not on Traefik itself

The impact depends on what sits behind the protected route: admin panels, internal config endpoints, secret-bearing APIs, or management actions. The advisory's lab chain demonstrated access to a protected /admin/exec endpoint, but that is conditional backend impact, not a built-in Traefik RCE.
Conditions required:
  • Sensitive backend functionality exists behind the bypassed route
  • The backend trusts Traefik to have already enforced auth
Where this breaks in practice:
  • Many backends add their own app-layer auth and reduce blast radius
  • This does not inherently provide host compromise or container escape
Detection/coverage: App logs are often the best signal: unauthorized hits on admin/internal endpoints from sessions or source IPs that never completed the expected auth flow.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo CISA KEV listing found and no reliable public exploitation reporting found as of 2026-06-05. I found public advisory material and PoC detail, but not campaign evidence.
Public PoC statusYes — the GitHub advisory itself includes a working PoC path set and expected vulnerable output using /api../admin and /api%2e%2e/admin, plus a lab scenario reaching a protected /admin/exec endpoint.
Researcher / reporterGitHub lists reporter H4ck2 on the advisory page; the advisory body attributes the report to WonYun / kyun0.
EPSSI did not find a public FIRST EPSS score for this CVE yet. Treat EPSS as unavailable / too new to rely on, not as evidence of low risk.
KEV statusNot KEV-listed.
CNA severityGitHub Security Advisory / Traefik CNA published High 7.8 with 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.
Affected versions<= v2.11.46, <= v3.6.17, and <= v3.7.1 according to the Traefik advisory.
Fixed versionsUpgrade to v2.11.48, v3.6.19, or v3.7.3. I did not find distro-specific backport guidance in the sources reviewed.
Exposure realityTraefik is a common internet-facing reverse proxy. As context, Censys previously reported over 14,000 exposed Traefik dashboards in public scans; that is not a CVE-specific count, but it supports the view that exposed Traefik footprint is non-trivial.
Disclosure timelineAdvisory published 2026-06-05; fix PR #13215 merged 2026-05-28; release v3.7.3 published 2026-06-04 and explicitly lists CVE-2026-48020 as fixed.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (6.4/10)

The decisive downward pressure is configuration specificity: the bug is only exploitable when a public PathPrefix + StripPrefix route and a separate protected route create the exact normalization gap. This is still a real unauthenticated auth bypass on edge infrastructure, but it is not a broad all-Traefik compromise and the blast radius is bounded by what the backend exposes behind that route design.

HIGH Affected version ranges and fixed versions
HIGH Technical exploit chain and PoC availability
MEDIUM Fleet-wide prevalence of the vulnerable routing pattern

Why this verdict

  • Unauthenticated remote is real — attacker position is internet-facing and no credentials or user interaction are needed once the bad route design exists, so this is not hand-wavy lab-only theory.
  • Config dependency cuts the reachable population — exploitation requires a public PathPrefix route, StripPrefix, a separate protected route, and backend-sensitive paths behind the same proxy. That compounding prerequisite stack pushes the score down from the vendor-style baseline.
  • Impact is boundary bypass, not platform takeover — the bug can expose admin/internal functionality and even enable downstream RCE *if* the backend already has an execution primitive, but Traefik itself is not handing out code execution or host compromise.

Why not higher?

This is not a universal pre-auth RCE, memory corruption bug, or auth bypass that fires on default installs. Real-world exploitability depends on an operator-created routing topology that many enterprises will simply not have, and some backends will still enforce their own auth after the proxy mistake.

Why not lower?

The attack is still unauthenticated, remote, and edge-facing where present, which always matters more than an internal-only footgun. If the vulnerable pattern exists in front of admin or internal APIs, the business impact can be immediate and ugly even without host-level compromise.

05 · Compensating Control

What to do — in priority order.

  1. Hunt for StripPrefix on public routes — Search file-provider configs, Helm values, Kubernetes CRDs, Docker labels, and Compose manifests for public routers that combine PathPrefix and StripPrefix. For a MEDIUM verdict there is no mitigation SLA — go straight to the 365-day remediation window, but this hunt is fast and should be done early because it identifies the small subset that actually matters.
  2. Tighten prefix boundaries — Where you cannot patch immediately, change public route matching from loose patterns to stricter ones the advisory verified in lab, such as PathRegexp(^/api(/|$)) or PathPrefix(/api/) with StripPrefix(/api/). There is no noisgate mitigation SLA for MEDIUM, so apply this opportunistically where config changes are easy while planning patching inside the remediation window.
  3. Block traversal-style payloads upstream — Add WAF/CDN/ingress filtering for requests containing .., %2e%2e, and similar encoded dot-segment tricks on public prefixes that feed Traefik. This is a solid temporary choke point, especially for internet-facing proxies, but it should be treated as a hardening measure rather than the primary fix.
  4. Require backend-side auth for admin paths — Do not rely solely on Traefik route boundaries for truly sensitive endpoints. If admin or internal APIs also enforce application auth, the proxy bypass collapses into a noisy but non-fatal routing bug.
  5. Patch to fixed Traefik releases — Move affected instances to v2.11.48, v3.6.19, or v3.7.3. For this MEDIUM assessment there is no mitigation SLA — go straight to the 365-day remediation window, but externally exposed edge proxies using the risky pattern should be prioritized well ahead of that outer deadline.
What doesn't work
  • MFA on the protected Traefik router alone does not help if the request never traverses that router's auth middleware.
  • Version-only vulnerability scans overstate urgency because the bug is highly config-dependent; they find exposed code paths, not exploitable deployments.
  • Assuming sanitizePath is enough is unsafe here; the bug is specifically about path handling after StripPrefix, so generic path sanitization settings are not the same as fixing this authorization boundary problem.
06 · Verification

Crowdsourced verification payload.

Run this on the Traefik host, container node, or CI image-validation job. Invoke it as sudo bash verify-cve-2026-48020.sh /etc/traefik or point it at the directory where your Traefik YAML/TOML/labels live; root is helpful if you want it to inspect Docker metadata and protected config paths. The script returns VULNERABLE when it finds both a vulnerable Traefik version and risky config indicators, PATCHED when the version is fixed, and UNKNOWN when it cannot prove either state.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# verify-cve-2026-48020.sh
# Detect likely exposure to CVE-2026-48020 (Traefik StripPrefix route-level auth bypass)
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

CFG_DIR="${1:-/etc/traefik}"
VERSION=""
FOUND_SOURCE=""
RISKY_CONFIG=0
STRIPPREFIX_FOUND=0
PATHPREFIX_FOUND=0
AUTH_HINT_FOUND=0

verlte() {
  [ "$1" = "$2" ] && return 0
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" = "$1" ]
}

vergte() {
  [ "$1" = "$2" ] && return 0
  [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ]
}

extract_semver() {
  echo "$1" | grep -Eo 'v?[0-9]+\.[0-9]+\.[0-9]+' | head -n1
}

check_fixed() {
  local v="$1"
  if vergte "$v" "v3.7.3"; then return 0; fi
  if vergte "$v" "v3.6.19" && verlte "$v" "v3.6.999"; then return 0; fi
  if vergte "$v" "v2.11.48" && verlte "$v" "v2.11.999"; then return 0; fi
  return 1
}

check_vuln_range() {
  local v="$1"
  if vergte "$v" "v3.7.0" && verlte "$v" "v3.7.1"; then return 0; fi
  if vergte "$v" "v3.6.0" && verlte "$v" "v3.6.17"; then return 0; fi
  if vergte "$v" "v2.11.0" && verlte "$v" "v2.11.46"; then return 0; fi
  return 1
}

# 1) Try local traefik binary
if command -v traefik >/dev/null 2>&1; then
  VERSION=$(traefik version 2>/dev/null | grep -Eo 'Version:\s*v?[0-9]+\.[0-9]+\.[0-9]+' | awk '{print $2}')
  if [ -n "$VERSION" ]; then
    FOUND_SOURCE="local traefik binary"
  fi
fi

# 2) Try Docker image / running container if version still unknown
if [ -z "$VERSION" ] && command -v docker >/dev/null 2>&1; then
  VERSION=$(docker ps --format '{{.Image}}' 2>/dev/null | grep -E '^traefik:v?[0-9]+\.[0-9]+\.[0-9]+' | head -n1 | sed 's/^traefik://')
  if [ -n "$VERSION" ]; then
    FOUND_SOURCE="running docker image"
  fi
fi

# 3) Try podman
if [ -z "$VERSION" ] && command -v podman >/dev/null 2>&1; then
  VERSION=$(podman ps --format '{{.Image}}' 2>/dev/null | grep -E '^traefik:v?[0-9]+\.[0-9]+\.[0-9]+' | head -n1 | sed 's/^traefik://')
  if [ -n "$VERSION" ]; then
    FOUND_SOURCE="running podman image"
  fi
fi

# Normalize version prefix
if [ -n "$VERSION" ]; then
  VERSION=$(extract_semver "$VERSION")
  case "$VERSION" in
    v*) ;;
    *) VERSION="v$VERSION" ;;
  esac
fi

# Config inspection
if [ -d "$CFG_DIR" ]; then
  if grep -RIEq 'stripPrefix|stripprefix' "$CFG_DIR" 2>/dev/null; then
    STRIPPREFIX_FOUND=1
  fi
  if grep -RIEq 'PathPrefix\(|pathprefix|PathRegexp\(' "$CFG_DIR" 2>/dev/null; then
    PATHPREFIX_FOUND=1
  fi
  if grep -RIEq 'basicAuth|digestAuth|forwardAuth|jwt|oidc|oauth|ipAllowList|ipWhiteList|middlewares:.*auth|authentication' "$CFG_DIR" 2>/dev/null; then
    AUTH_HINT_FOUND=1
  fi
fi

if [ "$STRIPPREFIX_FOUND" -eq 1 ] && [ "$PATHPREFIX_FOUND" -eq 1 ]; then
  RISKY_CONFIG=1
fi

# Decision logic
if [ -n "$VERSION" ] && check_fixed "$VERSION"; then
  echo "PATCHED: Traefik version $VERSION ($FOUND_SOURCE) is at or above a fixed release for its branch."
  exit 0
fi

if [ -n "$VERSION" ] && check_vuln_range "$VERSION"; then
  if [ "$RISKY_CONFIG" -eq 1 ]; then
    echo "VULNERABLE: Traefik version $VERSION is in an affected range and config under $CFG_DIR contains StripPrefix + PathPrefix indicators."
    if [ "$AUTH_HINT_FOUND" -eq 1 ]; then
      echo "NOTE: Auth-related middleware hints were also found; review for public-prefix to protected-path bypass patterns."
    fi
    exit 1
  fi
  echo "UNKNOWN: Traefik version $VERSION is in an affected range, but this script did not prove the risky routing pattern in $CFG_DIR."
  exit 2
fi

if [ -z "$VERSION" ]; then
  echo "UNKNOWN: Could not determine Traefik version from local binary or container runtime."
  exit 2
fi

echo "UNKNOWN: Detected version $VERSION, but branch/fix status could not be classified by this script."
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, inventory every internet-facing Traefik instance and immediately separate the small subset that actually uses StripPrefix on public path-based routes in front of admin or internal backends. For this MEDIUM assessment there is no noisgate mitigation SLA — go straight to the 365-day remediation window, so your formal deadline is to complete patching inside the noisgate remediation SLA of <= 365 days; in practice, exposed edge proxies matching the risky pattern should be moved first, while the rest can be handled as normal platform maintenance rather than emergency change work.

Sources

  1. Traefik GHSA-xf64-8mw2-4gr2 advisory
  2. Traefik release v3.7.3
  3. Traefik fix PR #13215
  4. CERT-FR advisory CERTFR-2026-AVI-0690
  5. Traefik StripPrefix documentation
  6. Traefik routers documentation
  7. Traefik entryPoints documentation
  8. Censys blog on exposed Traefik dashboards
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.