GHSA-C7JM-38GQ-H67H: Root-cause API Break Removes Unsafe Digest Nonce Default
Summary
The advisory describes a replay-based authentication bypass in http4k digest authentication caused by an insecure default nonce verifier that always returned true. The patch in commit 4f904b4692 removes the default nonce verifier and nonce generator parameters from the server-side DigestAuth extension, forcing callers to supply replay-related behavior explicitly. However, the later digest module code shown in commit 8a52b615b1 still exposes a default nonceVerifier = { true } in serverFilterExtensions.kt, which means the unsafe behavior remains present in that code path. Based on the provided sources, the remediation intent targets the root cause, but the available patch evidence is inconsistent and indicates incomplete eradication across module/layout variants.
Analysis
Vulnerability
GHSA-C7JM-38GQ-H67H reports an authentication bypass via replay attack in http4k digest authentication. The core issue is an insecure default nonce verifier that always returns true, disabling effective replay protection and allowing a captured Authorization header to be reused indefinitely.
The vulnerable server-side API exposed this behavior directly. In the earlier code, the digest filter accepted a default verifier of { true }, and the provider also stored the verifier with the same permissive default. That means applications could enable digest auth without making any replay-validation decision, yet still appear correctly configured.
qop: List<Qop> = listOf(Qop.Auth),
digestMode: DigestMode = DigestMode.Standard,
nonceGenerator: NonceGenerator = SECURE_NONCE,
nonceVerifier: NonceVerifier = { true },The same unsafe default also appeared in the provider constructor path:
private val nonceVerifier: NonceVerifier = { true },Because digest authentication relies on nonce semantics to limit replay, an always-accept verifier nullifies that control. The advisory summary is therefore consistent with the code shown in commit 4f904b4692 and the advisory itself at GitHub Security Advisory.
Patch
The primary remediation in commit 4f904b4692 is an API-breaking change that removes the default nonce generator and nonce verifier from the digest server filter signature. The changelog explicitly states: [Break] Remove default Nonce verifier option so avoid bad config.
The patched signature in that commit changes from optional replay-related parameters to mandatory ones:
qop: List<Qop> = listOf(Auth),
digestMode: DigestMode = Standard,
nonceGenerator: NonceGenerator,
nonceVerifier: NonceVerifier,The provider constructor is also tightened so the verifier is no longer defaulted internally:
private val nonceVerifier: NonceVerifier,This is the correct design direction because it removes the insecure-by-default behavior rather than attempting to document around it.
However, the provided source set also includes later digest-module code in commit 8a52b615b1 where http4k-security/digest/src/main/kotlin/org/http4k/filter/serverFilterExtensions.kt still shows:
nonceGenerator: NonceGenerator = SECURE_NONCE,
nonceVerifier: NonceVerifier = { true },That directly conflicts with the stated fix and with the earlier API break. The same commit also introduces shared nonce types in org.http4k.security, including typealias NonceVerifier = (Nonce) -> Boolean, but that refactor alone does not harden replay validation.
Review
Pros
- The remediation intent is source-grounded and appropriate: removing the default verifier addresses the root insecure default instead of merely warning users.
- The changelog in commit 4f904b4692 clearly marks the change as breaking, which is justified for a security-sensitive API.
- Making
nonceVerifiermandatory forces application developers to confront replay handling explicitly during integration. - Removing the provider-level default is important because it prevents accidental reintroduction through lower-level construction paths.
Cons
- The supplied sources are internally inconsistent: commit 8a52b615b1 still shows a default
nonceVerifier: NonceVerifier = { true }in the digest server filter extension. - The test updates shown for commit 4f904b4692 continue to pass
{ true }explicitly, which demonstrates API migration but does not demonstrate secure replay enforcement behavior. - No provided snippet shows a secure reference verifier implementation, nonce expiry policy, nonce-use tracking, or anti-replay state model. The patch removes the unsafe default but does not, from the supplied evidence, provide a safe turnkey replacement.
- If both code layouts correspond to supported branches or released artifacts, the vulnerability may persist in at least one module path despite the intended fix.
Verdict
Partial fix.
The fix in commit 4f904b4692 is the right root-cause-oriented change because it removes the insecure default nonce verifier from the public API and from the provider constructor. But the provided evidence from commit 8a52b615b1 still contains the same always-true default in the digest server filter extension, which means the remediation is not consistently applied across the shown codebase. For engineers assessing upgrade safety, this should be treated as incomplete until the released digest module no longer exposes nonceVerifier = { true } anywhere and secure replay-validation guidance or implementation is verified against the advisory at GitHub Security Advisory and the report summary at cvereports.com.
Recommended Labs
Try this vulnerability pattern yourself with hands-on labs.
- Broken Auth.api
Best direct match for the GHSA topic. The advisory is about authentication bypass caused by missing replay protection and unsafe digest-auth defaults. This lab maps to broken authentication weaknesses including improper authentication, session issues, and credential handling, which are highly relevant to nonce validation and replay resistance.
- BasicAuth.go
A good defensive lab for practicing how authentication middleware can fail in real services. While not digest-specific, it is closely aligned with the same class of server-side auth implementation mistakes that enable bypass when verification logic is weak or defaults are insecure.
- JWT2.js
Useful as a complementary lab on token-based authentication failure modes. The root lesson overlaps with this replay-attack advisory: authentication material must be validated with strong server-side checks, safe defaults, and anti-reuse protections rather than being implicitly trusted.