CVE-2026-88010
Traefik: BasicAuth singleflight coalescing reintroduces an unauthenticated username-enumeration timing oracle
Traefik is an open source HTTP reverse proxy and load balancer. From 3.6.11 until 3.7.13, checkPassword in pkg/middlewares/auth/basic_auth.go constructs the BasicAuth singleflight key from the submitted password and stored secret. Concurrent requests for absent usernames therefore coalesce on one key while configured usernames perform separate password hashes, creating an unauthenticated timing discrepancy that reveals whether a username exists. Sequential checks remain cost-equalized, Traefik v2 and Digest authentication are not affected, and the issue does not disclose credentials or bypass authentication. This issue is fixed in version 3.7.13.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
6.3
Traefik: BasicAuth singleflight coalescing reintroduces an unauthenticated username-enumeration timing oracle
Traefik is an open source HTTP reverse proxy and load balancer. From 3.6.11 until 3.7.13, checkPassword in pkg/middlewares/auth/basic_auth.go constructs the BasicAuth singleflight key from the submitted password and stored secret. Concurrent requests for absent usernames therefore coalesce on one key while configured usernames perform separate password hashes, creating an unauthenticated timing discrepancy that reveals whether a username exists. Sequential checks remain cost-equalized, Traefik v2 and Digest authentication are not affected, and the issue does not disclose credentials or bypass authentication. This issue is fixed in version 3.7.13.
- Record
CVE-2026-88010- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-208
- Updated
- 2026-11-02
EUVDEUVD-2026-84532
6.3
Traefik is an open source HTTP reverse proxy and load balancer. From 3.6.11 until 3.7.13, checkPassword in pkg/middlewares/auth/basic_auth.go constructs the BasicAuth singleflight key from the submitted password and stored secret. Concurrent requests for absent usernames therefore coalesce on one key while configured usernames perform separate password hashes, creating an unauthenticated timing discrepancy that reveals whether a username exists. Sequential checks remain cost-equalized, Traefik v2 and Digest authentication are not affected, and the issue does not disclose credentials or bypass authentication. This issue is fixed in version 3.7.13.
- Record
EUVD-2026-84532- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-8fcf-v89g-xpg6
6.3
Traefik: BasicAuth singleflight coalescing reintroduces an unauthenticated username-enumeration timing oracle
Summary
Traefik's BasicAuth middleware coalesces concurrent credential checks through a singleflight.Group to avoid hashing the same password many times at once. Since v3.6.11 the deduplication key was built from the submitted password plus the stored secret, so it depended on server state: a non-existent username collapsed onto one shared key while each configured username produced its own. Under attacker-controlled concurrency, a probe request arriving inside a leader request's in-flight window is served the leader's fast coalesced result when the username does not exist, but computes its own hash (slow) when the username exists — reintroducing, only in the concurrent case, the unauthenticated username-enumeration timing oracle that GHSA-g3hg-j4jv-cwfr had hardened for sequential probing. The fix derives the singleflight key from the submitted credentials (username and password) only, so it no longer depends on whether the account exists or on any stored secret. Traefik v2 is not affected: the v2.11 BasicAuth middleware does not use singleflight coalescing, and Digest authentication is not affected. The impact is limited to username enumeration; no credential disclosure or authentication bypass is possible.
The vulnerability originates on the v3.6 line, which has reached end of life; users on v3.6 or earlier v3.x must upgrade to v3.7.13 to receive the fix.
Patches
For more information
If you have any questions or comments about this advisory, please open an issue.
<details> <summary>Original Description</summary>
Summary
Confirmed. checkPassword derives the singleflight key from the stored secret, so the key encodes whether the submitted username exists:
- username absent,
secret == "", key= len(P) + ":" + P - username present, key
= len(P) + ":" + P + secret_T
Every non-existent username therefore lands on one shared key, while every configured username gets its own. singleflight.Group.Do makes a follower on an equal key block on the leader's in-flight computation and return the leader's result. So an attacker who sends a leader request with a junk username and password P, then sends the probe for target T with the same P late inside the leader's window, reads user existence directly off the probe's latency: coalesced (fast) means T does not exist, own hash (slow) means T does exist.
This is the exact information leak that the notFoundSecret dummy hash at line 127 exists to remove. Sequential probing is fully equalised (measured ratio 1.00x, so the fix for cwfr / 8j2h does work); the leak reappears only under attacker-controlled concurrency. Confirmed on the current v3.7 head, which already carries the 8mrf singleflight fix, and on master (no later fix exists).
Affected code
pkg/middlewares/auth/basic_auth.go:125(checkPassword)
Code analysis
pkg/middlewares/auth/basic_auth.go:119-131 matches the finding verbatim, including the cited line 125:
func (b *basicAuth) checkPassword(user, password string) bool { // :119
secret := b.auth.Secrets(user, b.auth.Realm) // "" when the user is absent
key := strconv.Itoa(len(password)) + ":" + password + secret // :124
match, _, _ := b.singleflightGroup.Do(key, func() (any, error) { // :125
if secret == "" {
_ = b.checkSecret(password, b.notFoundSecret) // :127 dummy hash, equal cost
return false, nil
}
return b.checkSecret(password, secret), nil
})
return match.(bool)
}
Two independent properties combine:
- The dummy hash equalises the cost of one lookup.
notFoundSecretis a configured user's real hash (slices.Collect(maps.Values(users))[0]), so absent and present users each perform exactly one hash of the same algorithm and cost. That is why the sequential control below is flat. - **The key partitions on existence, so coalescing…
- Record
GHSA-8fcf-v89g-xpg6- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-208
- Updated
- 2026-11-04
NVD
6.3
Traefik is an open source HTTP reverse proxy and load balancer. From 3.6.11 until 3.7.13, checkPassword in pkg/middlewares/auth/basic_auth.go constructs the BasicAuth singleflight key from the submitted password and stored secret. Concurrent requests for absent usernames therefore coalesce on one key while configured usernames perform separate password hashes, creating an unauthenticated timing discrepancy that reveals whether a username exists. Sequential checks remain cost-equalized, Traefik v2 and Digest authentication are not affected, and the issue does not disclose credentials or bypass authentication. This issue is fixed in version 3.7.13.
- Record
CVE-2026-88010- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/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
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N - Weakness
- CWE-208
- Updated
- 2026-11-02
OSV
6.3
Traefik: BasicAuth singleflight coalescing reintroduces an unauthenticated username-enumeration timing oracle
Traefik is an open source HTTP reverse proxy and load balancer. From 3.6.11 until 3.7.13, checkPassword in pkg/middlewares/auth/basic_auth.go constructs the BasicAuth singleflight key from the submitted password and stored secret. Concurrent requests for absent usernames therefore coalesce on one key while configured usernames perform separate password hashes, creating an unauthenticated timing discrepancy that reveals whether a username exists. Sequential checks remain cost-equalized, Traefik v2 and Digest authentication are not affected, and the issue does not disclose credentials or bypass authentication. This issue is fixed in version 3.7.13.
- Record
CVE-2026-88010- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-208
- Updated
- 2026-11-02
OSVGHSA-8fcf-v89g-xpg6
6.3
Traefik: BasicAuth singleflight coalescing reintroduces an unauthenticated username-enumeration timing oracle
Summary
Traefik's BasicAuth middleware coalesces concurrent credential checks through a singleflight.Group to avoid hashing the same password many times at once. Since v3.6.11 the deduplication key was built from the submitted password plus the stored secret, so it depended on server state: a non-existent username collapsed onto one shared key while each configured username produced its own. Under attacker-controlled concurrency, a probe request arriving inside a leader request's in-flight window is served the leader's fast coalesced result when the username does not exist, but computes its own hash (slow) when the username exists — reintroducing, only in the concurrent case, the unauthenticated username-enumeration timing oracle that GHSA-g3hg-j4jv-cwfr had hardened for sequential probing. The fix derives the singleflight key from the submitted credentials (username and password) only, so it no longer depends on whether the account exists or on any stored secret. Traefik v2 is not affected: the v2.11 BasicAuth middleware does not use singleflight coalescing, and Digest authentication is not affected. The impact is limited to username enumeration; no credential disclosure or authentication bypass is possible.
The vulnerability originates on the v3.6 line, which has reached end of life; users on v3.6 or earlier v3.x must upgrade to v3.7.13 to receive the fix.
Patches
For more information
If you have any questions or comments about this advisory, please open an issue.
<details> <summary>Original Description</summary>
Summary
Confirmed. checkPassword derives the singleflight key from the stored secret, so the key encodes whether the submitted username exists:
- username absent,
secret == "", key= len(P) + ":" + P - username present, key
= len(P) + ":" + P + secret_T
Every non-existent username therefore lands on one shared key, while every configured username gets its own. singleflight.Group.Do makes a follower on an equal key block on the leader's in-flight computation and return the leader's result. So an attacker who sends a leader request with a junk username and password P, then sends the probe for target T with the same P late inside the leader's window, reads user existence directly off the probe's latency: coalesced (fast) means T does not exist, own hash (slow) means T does exist.
This is the exact information leak that the notFoundSecret dummy hash at line 127 exists to remove. Sequential probing is fully equalised (measured ratio 1.00x, so the fix for cwfr / 8j2h does work); the leak reappears only under attacker-controlled concurrency. Confirmed on the current v3.7 head, which already carries the 8mrf singleflight fix, and on master (no later fix exists).
Affected code
pkg/middlewares/auth/basic_auth.go:125(checkPassword)
Code analysis
pkg/middlewares/auth/basic_auth.go:119-131 matches the finding verbatim, including the cited line 125:
func (b *basicAuth) checkPassword(user, password string) bool { // :119
secret := b.auth.Secrets(user, b.auth.Realm) // "" when the user is absent
key := strconv.Itoa(len(password)) + ":" + password + secret // :124
match, _, _ := b.singleflightGroup.Do(key, func() (any, error) { // :125
if secret == "" {
_ = b.checkSecret(password, b.notFoundSecret) // :127 dummy hash, equal cost
return false, nil
}
return b.checkSecret(password, secret), nil
})
return match.(bool)
}
Two independent properties combine:
- The dummy hash equalises the cost of one lookup.
notFoundSecretis a configured user's real hash (slices.Collect(maps.Values(users))[0]), so absent and present users each perform exactly one hash of the same algorithm and cost. That is why the sequential control below is flat. - **The key partitions on existence, so coalescing…
- Record
GHSA-8fcf-v89g-xpg6- CVSS 4.0
- 6.3 Medium
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-208
- Updated
- 2026-11-04
OSVGO-2026-6558 No score
Traefik: BasicAuth singleflight coalescing reintroduces an unauthenticated username-enumeration timing oracle
Traefik: BasicAuth singleflight coalescing reintroduces an unauthenticated username-enumeration timing oracle.
NOTE: The source advisory for this report contains additional versions that could not be automatically mapped to standard Go module versions.
(If this is causing false-positive reports from vulnerability scanners, please suggest an edit to the report.)
The additional affected modules and versions are: github.com/traefik/traefik from v3.6.11 before v3.7.13.
- Record
GO-2026-6558- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:12076-1 No score
traefik-3.7.13-1.1 on GA media
These are all security issues fixed in the traefik-3.7.13-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:12076-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
github.com/traefik/traefik/v3Go |
3.6.11 to 3.7.12 | 3.7.13 |
github.com/traefik/traefikGo |
Source text: > 0 | Not evaluated |
github.com/traefik/traefik/v3Go |
3.6.11 up to 3.7.13 | 3.7.13 |
github.com/traefik/traefikGo |
All versions | None known |
traefikopenSUSE:Tumbleweed From an advisory covering 5 CVEs |
before 3.7.13-1.1 | 3.7.13-1.1 |
Not evaluated means the source gave git commits or a range we can't read, so we can't tell which releases are affected. A fixed version beside it is the source’s own claim.
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | ||
| affected | OSV | |
| affected, facts | GitHub Advisories | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-88010 is a medium vulnerability (CVSS 6.3) in Traefik, published September 22, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.31%, the 23rd percentile. Fixed in github.com/traefik/traefik/v3 3.7.13.
References
github.com/traefik/traefik/security/advisories/GHSA-8fcf-v89g-xpg6
github.com/traefik/traefik/pull/13816
github.com/traefik/traefik/commit/ddc1bf4660b85fd61fafdd821eb8216fb1a0b130
github.com/traefik/traefik/releases/tag/v3.7.13
nvd.nist.gov/vuln/detail/CVE-2026-88010
github.com/advisories/GHSA-8fcf-v89g-xpg6
Show 7 moreShow less
Left out here: the rest of 2 source descriptions. The JSON record has them.