CVE-2026-69212 Overview
CVE-2026-69212 affects Http4s, a Scala interface for HTTP services. The FollowRedirect client middleware strips Authorization and Cookie headers only when a redirect changes authority. The authority comparison excludes the URI scheme, so a same-authority redirect from HTTPS to HTTP preserves credentials and transmits them over a plaintext connection. An attacker who can induce the downgrade and observe the network can capture those sensitive headers. The issue is classified as an information exposure weakness [CWE-200] and is fixed in versions 0.23.35 and 1.0.0-M47.
Critical Impact
Applications using the FollowRedirect client middleware leak Authorization headers and cookies over plaintext HTTP when a server responds with an HTTPS-to-HTTP same-host redirect.
Affected Products
- Http4s versions prior to 0.23.35
- Http4s 1.0.0 milestone releases prior to 1.0.0-M47
- Any Scala application invoking the FollowRedirect client middleware
Discovery Timeline
- 2026-09-15 - CVE-2026-69212 published to NVD
- 2026-09-16 - Last updated in NVD database
Technical Details for CVE-2026-69212
Vulnerability Analysis
The FollowRedirect middleware in Http4s automatically follows HTTP redirects on behalf of client applications. To prevent credential leakage across origins, the middleware inspects the redirect target and strips sensitive headers when the destination authority differs from the original request. The comparison uses only the URI authority component, which contains userinfo, host, and port. It omits the URI scheme.
When a server redirects a client from an https:// URL to an http:// URL on the same host and port, the authorities compare equal. The middleware preserves the Authorization header and any cookies and replays them on the follow-up plaintext request. Any on-path observer can read those credentials in cleartext.
Root Cause
The root cause is an incomplete equivalence check inside FollowRedirect.scala. The condition req.uri.authority != nextUri.authority treats HTTPS and HTTP as the same security context when host and port match. This violates the same-origin expectation that transport confidentiality is part of an origin's identity.
Attack Vector
Exploitation requires an attacker to induce the redirect and observe network traffic. Two common paths exist. First, an attacker who compromises or misconfigures the upstream server can issue a 302 redirect from https://api.example.com/resource to http://api.example.com/resource. Second, a network-adjacent attacker can inject a plaintext response on an unrelated leg of a workflow if the redirect target is attacker-controlled. Once the client follows the downgrade, the credentials flow over an unencrypted channel.
// Security patch in client/shared/src/main/scala/org/http4s/client/middleware/FollowRedirect.scala
fragment = uri.fragment.orElse(req.uri.fragment),
)
+ def sameSecurityContext(uri: Uri): Boolean = {
+ val schemeDowngrade =
+ uri.scheme.contains(Uri.Scheme.https) && nextUri.scheme.contains(Uri.Scheme.http)
+ uri.authority == nextUri.authority && !schemeDowngrade
+ }
+
def stripSensitiveHeaders(req: Request[F]): Request[F] =
- if (req.uri.authority != nextUri.authority)
+ if (!sameSecurityContext(req.uri))
req.transformHeaders(hs =>
Headers(hs.headers.filterNot(h => sensitiveHeaderFilter(h.name)))
)
else
req
def propagateCookies(req: Request[F]): Request[F] =
- if (req.uri.authority == nextUri.authority)
+ if (sameSecurityContext(req.uri))
cookies.foldLeft(req) { case (nextReq, cookie) =>
nextReq.addCookie(cookie.name, cookie.content)
}
Source: GitHub commit 6e825719b8d2f1538f2c49089c2dc81321a833b4. The patch introduces sameSecurityContext, which treats an HTTPS-to-HTTP transition as a different security context and forces both header stripping and cookie suppression on downgrade.
Detection Methods for CVE-2026-69212
Indicators of Compromise
- Outbound http:// requests carrying an Authorization header from services that normally speak HTTPS to a given host.
- Server-side redirect responses (301, 302, 307, 308) with a Location header whose scheme is http:// while the request arrived over HTTPS.
- Application logs from Http4s clients showing successful redirect chains that transition from HTTPS to HTTP on the same host and port.
Detection Strategies
- Perform a software composition analysis scan for Http4s versions below 0.23.35 and 1.0.0-M47 in Scala build files (build.sbt, Dependencies.scala).
- Enable client-side request logging on Http4s clients and alert on any request emitted with scheme=http that carries an Authorization or Cookie header.
- Instrument egress proxies to flag credential-bearing requests on port 80 destined for hosts that also serve HTTPS.
Monitoring Recommendations
- Monitor upstream services for unexpected HTTPS-to-HTTP redirect responses, which may signal misconfiguration or upstream compromise.
- Correlate authentication service logs with client-side redirect telemetry to identify credentials replayed on plaintext connections.
- Track dependency drift in CI pipelines so vulnerable Http4s versions cannot regress into production builds.
How to Mitigate CVE-2026-69212
Immediate Actions Required
- Upgrade Http4s client dependencies to 0.23.35 or 1.0.0-M47.
- Rotate any long-lived bearer tokens, API keys, or session cookies that were used with the FollowRedirect middleware against untrusted or third-party servers.
- Audit configured client middleware stacks and confirm the patched version is in effect at runtime, not just declared in build files.
Patch Information
The fix is available in Http4s release v0.23.35 and Http4s release v1.0.0-M47. Additional detail is available in GitHub Security Advisory GHSA-2rgg-r783-mrx4. The patched sameSecurityContext function strips sensitive headers and suppresses cookie propagation whenever the redirect transitions from HTTPS to HTTP.
Workarounds
- Disable the FollowRedirect middleware and handle redirects manually, validating the target scheme before replaying credentials.
- Wrap the client with a custom middleware that rejects any redirect whose Location scheme is http when the originating request used https.
- Restrict outbound HTTP egress at the network layer so downgrade attempts cannot complete a TCP connection on port 80.
# Configuration example: pin Http4s to a patched version in build.sbt
libraryDependencies ++= Seq(
"org.http4s" %% "http4s-ember-client" % "0.23.35",
"org.http4s" %% "http4s-client" % "0.23.35"
)
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.