providers/oauth2: fix CVE-2024-21637 (cherry-pick #8104) (#8105)

* providers/oauth2: fix CVE-2024-21637 (#8104)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* update changelog

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L <jens@goauthentik.io>
This commit is contained in:
gcp-cherry-pick-bot[bot] 2024-01-09 18:32:03 +01:00 committed by GitHub
parent 9f3ccfb7c7
commit 00ae97944a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 129 additions and 4 deletions

View File

@ -85,6 +85,25 @@ class TestAuthorize(OAuthTestCase):
) )
OAuthAuthorizationParams.from_request(request) OAuthAuthorizationParams.from_request(request)
def test_blocked_redirect_uri(self):
"""test missing/invalid redirect URI"""
OAuth2Provider.objects.create(
name=generate_id(),
client_id="test",
authorization_flow=create_test_flow(),
redirect_uris="data:local.invalid",
)
with self.assertRaises(RedirectUriError):
request = self.factory.get(
"/",
data={
"response_type": "code",
"client_id": "test",
"redirect_uri": "data:localhost",
},
)
OAuthAuthorizationParams.from_request(request)
def test_invalid_redirect_uri_empty(self): def test_invalid_redirect_uri_empty(self):
"""test missing/invalid redirect URI""" """test missing/invalid redirect URI"""
provider = OAuth2Provider.objects.create( provider = OAuth2Provider.objects.create(

View File

@ -75,6 +75,7 @@ PLAN_CONTEXT_PARAMS = "goauthentik.io/providers/oauth2/params"
SESSION_KEY_LAST_LOGIN_UID = "authentik/providers/oauth2/last_login_uid" SESSION_KEY_LAST_LOGIN_UID = "authentik/providers/oauth2/last_login_uid"
ALLOWED_PROMPT_PARAMS = {PROMPT_NONE, PROMPT_CONSENT, PROMPT_LOGIN} ALLOWED_PROMPT_PARAMS = {PROMPT_NONE, PROMPT_CONSENT, PROMPT_LOGIN}
FORBIDDEN_URI_SCHEMES = {"javascript", "data", "vbscript"}
@dataclass(slots=True) @dataclass(slots=True)
@ -175,6 +176,10 @@ class OAuthAuthorizationParams:
self.check_scope() self.check_scope()
self.check_nonce() self.check_nonce()
self.check_code_challenge() self.check_code_challenge()
if self.request:
raise AuthorizeError(
self.redirect_uri, "request_not_supported", self.grant_type, self.state
)
def check_redirect_uri(self): def check_redirect_uri(self):
"""Redirect URI validation.""" """Redirect URI validation."""
@ -212,10 +217,9 @@ class OAuthAuthorizationParams:
expected=allowed_redirect_urls, expected=allowed_redirect_urls,
) )
raise RedirectUriError(self.redirect_uri, allowed_redirect_urls) raise RedirectUriError(self.redirect_uri, allowed_redirect_urls)
if self.request: # Check against forbidden schemes
raise AuthorizeError( if urlparse(self.redirect_uri).scheme in FORBIDDEN_URI_SCHEMES:
self.redirect_uri, "request_not_supported", self.grant_type, self.state raise RedirectUriError(self.redirect_uri, allowed_redirect_urls)
)
def check_scope(self): def check_scope(self):
"""Ensure openid scope is set in Hybrid flows, or when requesting an id_token""" """Ensure openid scope is set in Hybrid flows, or when requesting an id_token"""

View File

@ -6,6 +6,7 @@ from hashlib import sha256
from re import error as RegexError from re import error as RegexError
from re import fullmatch from re import fullmatch
from typing import Any, Optional from typing import Any, Optional
from urllib.parse import urlparse
from django.http import HttpRequest, HttpResponse from django.http import HttpRequest, HttpResponse
from django.utils import timezone from django.utils import timezone
@ -54,6 +55,7 @@ from authentik.providers.oauth2.models import (
RefreshToken, RefreshToken,
) )
from authentik.providers.oauth2.utils import TokenResponse, cors_allow, extract_client_auth from authentik.providers.oauth2.utils import TokenResponse, cors_allow, extract_client_auth
from authentik.providers.oauth2.views.authorize import FORBIDDEN_URI_SCHEMES
from authentik.sources.oauth.models import OAuthSource from authentik.sources.oauth.models import OAuthSource
from authentik.stages.password.stage import PLAN_CONTEXT_METHOD, PLAN_CONTEXT_METHOD_ARGS from authentik.stages.password.stage import PLAN_CONTEXT_METHOD, PLAN_CONTEXT_METHOD_ARGS
@ -205,6 +207,10 @@ class TokenParams:
).from_http(request) ).from_http(request)
raise TokenError("invalid_client") raise TokenError("invalid_client")
# Check against forbidden schemes
if urlparse(self.redirect_uri).scheme in FORBIDDEN_URI_SCHEMES:
raise TokenError("invalid_request")
self.authorization_code = AuthorizationCode.objects.filter(code=raw_code).first() self.authorization_code = AuthorizationCode.objects.filter(code=raw_code).first()
if not self.authorization_code: if not self.authorization_code:
LOGGER.warning("Code does not exist", code=raw_code) LOGGER.warning("Code does not exist", code=raw_code)

View File

@ -137,6 +137,62 @@ helm upgrade authentik authentik/authentik -f values.yaml --version ^2023.10
- web/admin: fix @change handler for ak-radio elements (#7348) - web/admin: fix @change handler for ak-radio elements (#7348)
- web/admin: fix role form reacting to enter (#7330) - web/admin: fix role form reacting to enter (#7330)
## Fixed in 2023.10.3
- ci: explicitly give write permissions to packages (cherry-pick #7428) (#7430)
- core: fix worker beat toggle inverted (cherry-pick #7508) (#7509)
- events: fix gdpr compliance always running (cherry-pick #7491) (#7505)
- providers/oauth2: set auth_via for token and other endpoints (cherry-pick #7417) (#7427)
- providers/proxy: fix closed redis client (cherry-pick #7385) (#7429)
- root: Improve multi arch Docker image build speed (cherry-pick #7355) (#7426)
- sources/oauth: fix patreon (cherry-pick #7454) (#7456)
- stages/email: fix duplicate querystring encoding (cherry-pick #7386) (#7425)
- web: bugfix: broken backchannel selector (cherry-pick #7480) (#7507)
- web/admin: fix html error on oauth2 provider page (cherry-pick #7384) (#7424)
- web/flows: attempt to fix bitwareden android compatibility (cherry-pick #7455) (#7457)
## Fixed in 2023.10.4
- ci: fix permissions for release pipeline to publish binaries (cherry-pick #7512) (#7621)
- core: bump golang from 1.21.3-bookworm to 1.21.4-bookworm (cherry-pick #7483) (#7622)
- events: don't update internal service accounts unless needed (cherry-pick #7611) (#7640)
- events: fix missing model\_\* events when not directly authenticated (cherry-pick #7588) (#7597)
- events: sanitize functions (cherry-pick #7587) (#7589)
- providers/proxy: Fix duplicate cookies when using file system store. (cherry-pick #7541) (#7544)
- providers/scim: fix missing schemas attribute for User and Group (cherry-pick #7477) (#7596)
- root: specify node and python versions in respective config files, deduplicate in CI (#7620)
- security: fix [CVE-2023-48228](../../security/CVE-2023-48228.md), Reported by [@Sapd](https://github.com/Sapd) (#7666)
- stages/email: use uuid for email confirmation token instead of username (cherry-pick #7581) (#7584)
- web/admin: fix admins not able to delete MFA devices (#7660)
## Fixed in 2023.10.5
- blueprints: improve file change handler (cherry-pick #7813) (#7934)
- events: add better fallback for sanitize_item to ensure everything can be saved as JSON (cherry-pick #7694) (#7937)
- events: fix lint (#7700)
- events: include user agent in events (cherry-pick #7693) (#7938)
- providers/scim: change familyName default (cherry-pick #7904) (#7930)
- root: don't show warning when app has no URLs to import (cherry-pick #7765) (#7935)
- root: Fix cache related image build issues (cherry-pick #7831) (#7932)
- stages/email: improve error handling for incorrect template syntax (cherry-pick #7758) (#7936)
- tests: fix flaky tests (cherry-pick #7676) (#7939)
- web: dark/light theme fixes (#7872)
- web: fix overflow glitch on ak-page-header (cherry-pick #7883) (#7931)
- web/admin: always show oidc well-known URL fields when they're set (#7560)
- web/user: fix search not updating app (cherry-pick #7825) (#7933)
## Fixed in 2023.10.6
- core: fix PropertyMapping context not being available in request context
- outposts: disable deployment and secret reconciler for embedded outpost in code instead of in config (cherry-pick #8021) (#8024)
- outposts: fix Outpost reconcile not re-assigning managed attribute (cherry-pick #8014) (#8020)
- providers/oauth2: fix [CVE-2024-21637](../../security/CVE-2024-21637.md), Reported by [@lauritzh](https://github.com/lauritzh) (#8104)
- providers/oauth2: remember session_id from initial token (cherry-pick #7976) (#7977)
- providers/proxy: use access token (cherry-pick #8022) (#8023)
- rbac: fix error when looking up permissions for now uninstalled apps (cherry-pick #8068) (#8070)
- sources/oauth: fix missing get_user_id for OIDC-like sources (Azure AD) (#7970)
- web/flows: fix device picker incorrect foreground color (cherry-pick #8067) (#8069)
## API Changes ## API Changes
#### What's New #### What's New

View File

@ -0,0 +1,39 @@
# CVE-2024-21637
_Reported by [@lauritzh](https://github.com/lauritzh)_
## XSS in Authentik via JavaScript-URI as Redirect URI and form_post Response Mode
### Summary
Given an OAuth2 provider configured with allowed redirect URIs set to `*` or `.*`, an attacker can send an OAuth Authorization request using `response_mode=form_post` and setting `redirect_uri` to a malicious URI, to capture authentik's session token.
### Patches
authentik 2023.8.6 and 2023.10.6 fix this issue.
### Impact
The impact depends on the attack scenario. In the following I will describe the two scenario that were identified for Authentik.
#### Redirect URI Misconfiguration
While advising that this may cause security issues, Authentik generally allows wildcards as Redirect URI. Therefore, using a wildcard-only effectively allowing arbitrary URLS is possible misconfiguration that may be present in real-world instances.
In such cases, unauthenticated and unprivileged attackers can perform the above described actions.
### User with (only) App Administration Permissions
A more likely scenario is an administrative user (e.g. a normal developer) having only permissions to manage applications.
This relatively user could use the described attacks to perform a privilege escalation.
### Workaround
It is recommended to upgrade to the patched version of authentik. If not possible, ensure that OAuth2 providers do not use a wildcard (`*` or `.*`) value as allowed redirect URI setting. (This is _not_ exploitable if part of the redirect URI has a wildcard, for example `https://foo-.*\.bar\.com`)
### For more information
If you have any questions or comments about this advisory:
- Email us at [security@goauthentik.io](mailto:security@goauthentik.io)

View File

@ -407,6 +407,7 @@ const docsSidebar = {
}, },
items: [ items: [
"security/policy", "security/policy",
"security/CVE-2024-21637",
"security/CVE-2023-48228", "security/CVE-2023-48228",
"security/GHSA-rjvp-29xq-f62w", "security/GHSA-rjvp-29xq-f62w",
"security/CVE-2023-39522", "security/CVE-2023-39522",