CVE-2026-54148 Overview
CVE-2026-54148 is an authentication bypass vulnerability in http4k, a functional toolkit for Kotlin HTTP applications. The DigestAuthProvider.verify function in http4k-security-digest fails to compare the uri parameter in an Authorization: Digest response against the actual request URL. An attacker who captures a valid Digest authentication response can replay it against another URL served by the same realm. This breaks the per-request-URI binding that Digest authentication relies on and can grant unauthorized read or write access to protected endpoints. The issue is tracked as [CWE-294: Authentication Bypass by Capture-replay].
Critical Impact
Captured Digest credentials can be replayed against any URL in the same authentication realm, enabling unauthorized access to protected resources without credential theft.
Affected Products
- http4k http4k-security-digest module prior to 4.51.0.0
- http4k http4k-security-digest module prior to 5.42.0.0
- http4k http4k-security-digest module prior to 6.50.0.0
Discovery Timeline
- 2026-09-18 - CVE-2026-54148 published to NVD
- 2026-09-24 - Last updated in NVD database
Technical Details for CVE-2026-54148
Vulnerability Analysis
HTTP Digest Access Authentication requires the client to compute a response hash bound to a specific request URI. The server must validate that the uri parameter in the Authorization: Digest header matches the actual request URL. This binding prevents an attacker who captures one authenticated request from replaying the credentials against a different resource.
In vulnerable versions of http4k, the verify function in DigestAuthProvider accepts only the credentials and HTTP method. It never receives or checks the request URI, so the per-request binding is effectively absent. An attacker positioned to observe a single authenticated request, for example through a compromised proxy or logging system, can extract the Authorization header and replay it against any URL protected by the same realm and nonce window.
Root Cause
The root cause is a missing input comparison. The server accepts the client-supplied digestUri value as valid without ever comparing it to the URL the request targets. Because the nonce and response hash remain valid for the nonce lifetime, credentials captured for /read can be replayed against /admin/write within the same realm.
Attack Vector
Exploitation requires network access and a way to observe at least one valid Digest-authenticated request. The attacker copies the intact Authorization: Digest header onto a new request targeting a different URI in the same realm. The server validates the response hash, realm, and nonce, but never confirms the URI, and grants access.
// Patch: core/security/digest/src/main/kotlin/org/http4k/filter/serverFilterExtensions.kt
return Filter { next ->
filter@{ request ->
val credentials = provider.digestCredentials(request) ?: return@filter provider.generateChallenge()
- if (!provider.verify(credentials, request.method)) return@filter Response(UNAUTHORIZED)
+ if (!provider.verify(credentials, request.method, request.uri.toString())) return@filter Response(UNAUTHORIZED)
next(usernameKey?.let { request.with(it of credentials.username) } ?: request)
}
// Patch: core/security/digest/src/main/kotlin/org/http4k/security/digest/DigestAuthProvider.kt
- fun verify(credentials: DigestCredential, method: Method): Boolean {
+ fun verify(credentials: DigestCredential, method: Method, requestUri: String): Boolean {
val digestEncoder = DigestEncoder(MessageDigest.getInstance(algorithm))
if (credentials.algorithm != null && credentials.algorithm != algorithm) return false
if (credentials.realm != realm) return false
+ if (credentials.digestUri != requestUri) return false
if (!nonceVerifier(credentials.nonce)) return false
Source: http4k commit 725f1b9
Detection Methods for CVE-2026-54148
Indicators of Compromise
- Repeated identical Authorization: Digest header values observed across requests to different URIs within a short window.
- Requests where the uri= parameter inside the Digest header does not match the actual HTTP request path.
- Successful authenticated access to sensitive endpoints from clients that never performed the initial WWW-Authenticate challenge exchange for that URI.
Detection Strategies
- Parse the Authorization: Digest header at a reverse proxy or WAF and reject requests where the uri parameter does not equal the request-line URI.
- Correlate nonce reuse across differing request URIs from the same or different source addresses to surface replay behavior.
- Inventory build manifests (build.gradle, pom.xml) for http4k-security-digest versions below 4.51.0.0, 5.42.0.0, or 6.50.0.0.
Monitoring Recommendations
- Enable verbose access logging on Digest-protected endpoints, capturing the full Authorization header for security review.
- Alert on authenticated requests to administrative or write endpoints that lack a preceding 401 challenge from the same client session.
- Track dependency-scanning output in CI for the affected http4k module versions and fail builds on vulnerable ranges.
How to Mitigate CVE-2026-54148
Immediate Actions Required
- Upgrade http4k-security-digest to 4.51.0.0, 5.42.0.0, or 6.50.0.0 depending on the major version in use.
- Rotate any nonce-generation secrets and shorten nonce validity windows to reduce the replay window before patching.
- Audit access logs for suspicious reuse of Authorization: Digest headers against multiple URIs.
Patch Information
The fix is delivered in http4k versions 4.51.0.0, 5.42.0.0, and 6.50.0.0. The DigestAuthProvider.verify signature was extended to accept the request URI and now rejects credentials whose digestUri value does not match the actual request path. Full details are available in GitHub Security Advisory GHSA-p28p-j94q-pg32 and the http4k 6.50.0.0 release notes.
Workarounds
- Place a reverse proxy in front of http4k that parses and validates the uri parameter in the Authorization: Digest header against the actual request URI.
- Where feasible, migrate protected endpoints from Digest authentication to a token-based scheme such as mutual TLS or short-lived bearer tokens.
- Restrict Digest-protected endpoints to trusted network segments until patched builds are deployed.
# Verify installed http4k-security-digest version in a Gradle project
./gradlew dependencyInsight --dependency http4k-security-digest
# Pin patched versions in build.gradle.kts
# implementation("org.http4k:http4k-security-digest:6.50.0.0")
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.
