CVE-2026-41569
Description
authentik's WS-Federation provider allows attackers to redirect signed login responses to attacker-controlled endpoints via a wreply parameter bypass.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
authentik's WS-Federation provider allows attackers to redirect signed login responses to attacker-controlled endpoints via a wreply parameter bypass.
Vulnerability
Prior to version 2026.2.3, authentik's WS-Federation provider incorrectly validated the user-supplied wreply parameter using a raw string prefix check instead of proper URL parsing. This allowed an attacker to craft a login link with a wreply value on a different origin that would pass the check, such as https://portal.example.com.evil.tld/ [1]. Only WS-Federation providers with a prefix-ambiguous Reply URL are affected.
Exploitation
An attacker needs to be able to craft a login link. By supplying a malicious wreply value that starts with the configured Reply URL but points to an attacker-controlled domain, the victim's browser will POST the signed WS-Federation login response to the attacker's infrastructure [1].
Impact
An attacker can exfiltrate signed WS-Federation login responses. The victim's browser automatically POSTs the response to the attacker-controlled wreply URL. This signed authentication artifact can be replayable to the legitimate ACS endpoint, enabling victim impersonation in the target application [1].
Mitigation
This issue is fixed in authentik versions 2025.12.5 and 2026.2.3. As a workaround, administrators can configure the WS-Federation provider's Reply URL with a specific path (e.g., https://portal.example.com/wsfed/acs) to prevent the host-extension bypass, though upgrading is strongly preferred [1].
AI Insight generated on Jun 2, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
100f0cfe6e40binternal: Automated internal backport: CVE-2026-41569.sec.patch to authentik-main (#22301)
5 files changed · +57 −2
authentik/enterprise/providers/ws_federation/processors/sign_in.py+4 −1 modified@@ -1,4 +1,5 @@ from dataclasses import dataclass +from urllib.parse import urlparse from django.http import HttpRequest from django.shortcuts import get_object_or_404 @@ -55,7 +56,9 @@ def parse(request: HttpRequest) -> SignInRequest: _, provider = req.get_app_provider() if not req.wreply: req.wreply = provider.acs_url - if not req.wreply.startswith(provider.acs_url): + reply = urlparse(req.wreply) + configured = urlparse(provider.acs_url) + if not (reply[:2] == configured[:2] and reply.path.startswith(configured.path)): raise ValueError("Invalid wreply") return req
authentik/enterprise/providers/ws_federation/processors/sign_out.py+4 −1 modified@@ -1,4 +1,5 @@ from dataclasses import dataclass +from urllib.parse import urlparse from django.http import HttpRequest from django.shortcuts import get_object_or_404 @@ -32,7 +33,9 @@ def parse(request: HttpRequest) -> SignOutRequest: _, provider = req.get_app_provider() if not req.wreply: req.wreply = provider.acs_url - if not req.wreply.startswith(provider.acs_url): + reply = urlparse(req.wreply) + configured = urlparse(provider.acs_url) + if not (reply[:2] == configured[:2] and reply.path.startswith(configured.path)): raise ValueError("Invalid wreply") return req
authentik/enterprise/providers/ws_federation/tests/test_sign_in.py+15 −0 modified@@ -27,12 +27,27 @@ def setUp(self): name=generate_id(), authorization_flow=self.flow, signing_kp=self.cert, + acs_url="https://t.goauthentik.io", + audience="foo", ) self.app = Application.objects.create( name=generate_id(), slug=generate_id(), provider=self.provider ) self.factory = RequestFactory() + def test_wreply(self): + request = self.factory.get( + "/?wreply=https://t.goauthentik.io/foo&wa=wsignin1.0&wtrealm=foo", + user=get_anonymous_user(), + ) + SignInRequest.parse(request) + with self.assertRaises(ValueError): + request = self.factory.get( + "/?wreply=https://t.goauthentik.io.invalid.com&wa=wsignin1.0&wtrealm=foo", + user=get_anonymous_user(), + ) + SignInRequest.parse(request) + def test_token_gen(self): request = self.factory.get("/", user=get_anonymous_user()) proc = SignInProcessor(
locale/en/dictionaries/software-terms.txt+1 −0 modified@@ -164,3 +164,4 @@ yamltags zxcvbn ~uuid ~uuids +wreply
website/docs/security/cves/CVE-2026-41569.md+33 −0 added@@ -0,0 +1,33 @@ +# CVE-2026-41569 + +_Reported by [@jmecom](https://github.com/jmecom) and [@AyushParkara](https://github.com/AyushParkara)_ + +## WS-Federation wreply Origin Bypass (CVE-2026-41569) + +### Summary + +The WS-Federation provider validates the user-supplied `wreply` parameter using a raw string prefix check rather than proper URL parsing. An attacker who can craft a login link can supply a `wreply` value on a different origin that passes the check (e.g. `https://portal.example.com.evil.tld/`), causing the victim's browser to POST the signed WS-Federation login response to attacker-controlled infrastructure. + +### Patches + +authentik 2025.12.5 and 2026.2.3 fix this issue. + +### Impact + +The WS-Federation sign-in processor accepted any `wreply` whose string value started with the configured Reply URL, not correctly comparing the domain. + +Once accepted, the attacker-controlled `wreply` is used as the autosubmit destination, and the victim's browser immediately POSTs the signed WS-Federation response (`wresult`) to that URL. The response is a valid signed authentication artifact; in many relying-party configurations it is replayable to the legitimate ACS endpoint, enabling victim impersonation in the target application. + +The fix replaces the string prefix check with proper URL parsing, comparing scheme, host, and path independently: + +Only WS-Federation providers (an enterprise feature) with a prefix-ambiguous Reply URL are affected. If the Reply URL is already path-specific (e.g. `https://portal.example.com/wsfed/acs`), the host-extension bypass does not apply. + +### Workarounds + +Configure the WS-Federation provider's Reply URL with a specific path (e.g. `https://portal.example.com/wsfed/acs`) rather than a bare hostname. This prevents the host-extension bypass without patching, though upgrading is strongly preferred. + +### For more information + +If you have any questions or comments about this advisory: + +- Email us at [security@goauthentik.io](mailto:security@goauthentik.io)
Vulnerability mechanics
Synthesis attempt was rejected by the grounding validator. Re-run pending.
References
1News mentions
0No linked articles in our index yet.