OAuth 20 Server, PKCE Implementation Flaw, CVE-2024-XXXXX (Medium)

Listen to this Post

How the mentioned CVE works

The vulnerability resides in the improper validation of the `code_verifier` parameter during the OAuth 2.0 token exchange for PKCE (Proof Key for Code Exchange) flows. According to RFC 7636, a `code_verifier` must be a cryptographically random string using specific characters (A-Z, a-z, 0-9, hyphen, period, underscore, and tilde) with a length between 43 and 128 characters. However, the affected server implementation fails to enforce these requirements.
Specifically, when an authorization request includes code_challenge_method=S256, the server’s PKCE module (lib/pkce/pkce.js) does not validate the verifier’s length or character set. It only checks that the verifier is a non-empty string before hashing it for comparison with the stored code_challenge. Consequently, even a one-character verifier like “z” is accepted for S256 flows, which is a clear violation of the RFC.
The token endpoint logic (lib/grant-types/authorization-code-grant-type.js) then compares the hash of the provided `code_verifier` against the stored `code_challenge` without any format or length validation. If the hash matches, the token exchange succeeds. Furthermore, the authorization code is not invalidated after a failed verifier attempt. This allows an attacker to repeatedly try different `code_verifier` guesses online until a match is found.
An attacker who intercepts an authorization code can therefore perform an online brute-force attack. For example, if the original `code_challenge` was derived from the verifier “z”, the attacker can send token requests with guessed verifiers (e.g., “a”, “b”, …, “z”) until the correct one is accepted. The server returns `invalid_grant` for incorrect guesses but does not revoke the code, enabling the attacker to continue guessing. Once the correct verifier is found, the server issues access and refresh tokens, fully compromising the OAuth session.
This weakness significantly weakens PKCE’s security guarantees, as it transforms the verifier from a high-entropy secret into a low-entropy, brute-forceable token. The issue was confirmed in the affected server implementation, with a proof of concept demonstrating successful token issuance after only 26 attempts (guessing a one-character verifier). The root cause is the missing enforcement of RFC 7636’s ABNF for the code_verifier, coupled with the lack of authorization code revocation on failed attempts.

DailyCVE Form

Platform: OAuth 2.0 Server
Version: Versions prior to 3.1.1
Vulnerability : PKCE Brute Force
Severity: Medium (CVSS 6.5)
date: 2024-03-15

Prediction: Patch expected 2024-05-01

What Undercode Say

The following analytics and commands can be used to detect or mitigate this vulnerability.

Bash Commands for Detection

Check if the OAuth server accepts short code_verifiers
This script tests for the vulnerability by attempting a token exchange with a one-character verifier
!/bin/bash
AUTH_CODE="stolen-auth-code"
CLIENT_ID="client1"
CLIENT_SECRET="s3cret"
REDIRECT_URI="https://client.example/callback"
TOKEN_ENDPOINT="https://oauth.example/token"
for guess in {a..z}; do
curl -s -X POST "$TOKEN_ENDPOINT" \
-d "grant_type=authorization_code" \
-d "client_id=$CLIENT_ID" \
-d "client_secret=$CLIENT_SECRET" \
-d "code=$AUTH_CODE" \
-d "redirect_uri=$REDIRECT_URI" \
-d "code_verifier=$guess" | grep -q "access_token" && echo "Success with guess: $guess" && break
done

Code Snippet for Fix (Node.js)

// lib/pkce/pkce.js - Add RFC7636 validation
const crypto = require('crypto');
function isValidCodeVerifier(verifier) {
const regex = /^[A-Za-z0-9-.<em>~]{43,128}$/;
return regex.test(verifier);
}
function getHashForCodeChallenge(verifier) {
if (!verifier || typeof verifier !== 'string') {
throw new Error('code_verifier is required');
}
if (!isValidCodeVerifier(verifier)) {
throw new Error('code_verifier must be 43-128 characters of [A-Za-z0-9-.</em>~]');
}
return crypto.createHash('sha256').update(verifier).digest('base64url');
}

Exploit

An attacker can exploit this vulnerability by:

1. Intercepting an OAuth authorization code during transmission.

  1. Generating a list of potential `code_verifier` values, starting with the shortest possible (e.g., one character) and increasing in length and complexity.
  2. Sending repeated token requests to the `/token` endpoint, each time with a different guessed code_verifier.
  3. Observing that the server returns `invalid_grant` for incorrect guesses but does not revoke the authorization code.
  4. Continuing until a guess produces a successful token response, yielding access and refresh tokens.
    The attack is feasible even with low entropy because the server accepts verifiers that are far shorter than the required 43 characters. The lack of rate limiting or code invalidation on failed attempts further enables the brute-force attack.

Protection from this CVE

To protect against this vulnerability:

  • Update the OAuth server to the latest patched version (e.g., version 3.1.2 or higher) that enforces RFC 7636 validation.
  • Implement strict validation of the `code_verifier` before hashing, rejecting any verifier that does not conform to the length and character set requirements.
  • Invalidate the authorization code after a configurable number of failed token exchange attempts (e.g., 3-5 failures) to prevent brute-force attacks.
  • Apply rate limiting on the `/token` endpoint for requests with invalid `code_verifier` values.
  • Monitor logs for repeated `invalid_grant` errors from the same authorization code, which may indicate an ongoing brute-force attempt.
  • Ensure that all OAuth clients generate high-entropy `code_verifier` strings (e.g., using `crypto.randomBytes(32)` in Node.js) that comply with RFC 7636.

Impact

  • Token Theft: An attacker who intercepts an authorization code can redeem it for access and refresh tokens, gaining unauthorized access to the user’s resources.
  • Bypass of PKCE Protection: The vulnerability completely undermines the security benefits of PKCE, which is designed to prevent authorization code interception attacks.
  • Session Hijacking: With the obtained tokens, the attacker can impersonate the legitimate user and perform actions on their behalf.
  • Widespread Risk: Any OAuth client that relies on the affected server for PKCE is vulnerable, especially public clients (e.g., mobile apps, single-page applications) that cannot store client secrets securely.
  • Compliance Violations: This flaw may violate security and privacy regulations (e.g., GDPR, HIPAA) if user data is exposed through token theft.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top