(oauthlib), PKCE Timing Side-Channel, CVE-2026-49265 (Medium) -DC-Sep2026-2610

Listen to this Post

CVE-2026-49265: PKCE Timing Side-Channel in oauthlib Authorization Code Grant
A timing side-channel vulnerability exists in the Proof Key for Code Exchange (PKCE, RFC 7636) implementation of the Authorization Code Grant flow within the `oauthlib` Python library. The vulnerability resides in the token endpoint’s code verifier comparison logic. Specifically, the `code_challenge_method_plain` function historically used Python’s standard `==` operator for string comparison instead of a constant-time comparison function, such as hmac.compare_digest(). Python’s `==` operator employs short-circuit evaluation: it returns `False` immediately if the string lengths differ, and when lengths are equal, it compares characters from left to right, aborting at the first mismatched character. Consequently, the time taken to perform the comparison varies linearly with the length of the common prefix between the attacker-supplied `code_verifier` and the stored code_challenge. This creates a measurable timing oracle. An attacker who has intercepted an authorization_code—for example, via a Custom URI Scheme Hijacking attack—can repeatedly send requests to the `/token` endpoint and measure response times. By statistically analyzing these timings, the attacker can recover the `code_verifier` character by character. While PKCE is designed to block such attacks by requiring the verifier, this implementation flaw reintroduces the risk. Once the full `code_verifier` is recovered, the attacker can exchange the intercepted authorization code for an access token, leading to account takeover. The vulnerability is classified as CWE-208 (Observable Timing Discrepancy). Practical exploitability is limited by the single-use nature of authorization codes and network noise, but the issue warrants a defense-in-depth correction. The recommended fix is to replace `==` with `hmac.compare_digest()` for constant-time comparison, ensuring that the time taken to compare the verifier and challenge is independent of their contents.

DailyCVE Form

Platform: oauthlib
Version: < 3.3.2
Vulnerability: PKCE Timing Side-Channel
Severity: Medium
date: 2026-09-28

Prediction: 2026-10-12

What Undercode Say

Analytics

Bash commands and code snippets to analyze the vulnerability locally:

Clone the oauthlib repository and inspect the vulnerable function
git clone https://github.com/oauthlib/oauthlib.git
cd oauthlib
grep -n "def code_challenge_method_plain" oauthlib/oauth2/rfc6749/grant_types/authorization_code.py
Python script to measure timing differences in the vulnerable comparison
import time
import hmac
import statistics
def vulnerable_compare(a, b):
return a == b Vulnerable: short-circuit evaluation
def constant_time_compare(a, b):
return hmac.compare_digest(a, b) Safe
Simulate the attack scenario with controlled inputs
challenge = "A" 50
test_cases = [
"B" + "A" 49, Wrong first character
"A" 49 + "B", Correct prefix, wrong last character
]
for verifier in test_cases:
times = []
for _ in range(10_000_000):
start = time.perf_counter_ns()
vulnerable_compare(verifier, challenge)
times.append(time.perf_counter_ns() - start)
print(f"Input: {verifier[:5]}... -> Mean: {statistics.mean(times):.2f} ns")

Exploit: (Educational Purposes!)

The following steps illustrate how a timing side-channel attack could be conducted in a controlled environment. This is strictly for educational and defensive purposes to demonstrate the risk.
1. Intercept the Authorization Code: The attacker intercepts the `authorization_code` returned to a malicious application via a Custom URI Scheme Hijacking vulnerability. Without PKCE, this code could be exchanged directly for an access token. With PKCE, the attacker also needs the code_verifier.
2. Initiate Timing Measurement: The attacker sends repeated requests to the `/token` endpoint, each time supplying a guessed `code_verifier` along with the intercepted authorization_code. The server responds with an error indicating an invalid verifier, but the response time varies based on how many leading characters of the guess match the stored code_challenge.
3. Recover the Verifier Character by Character: The attacker uses statistical analysis to detect the timing difference. A guess that shares a longer common prefix with the challenge will take slightly longer to reject. By iterating through candidate characters for each position and measuring the response time over many requests, the attacker can identify the correct character for each position.
4. Complete the Token Exchange: Once the full `code_verifier` is recovered, the attacker sends a final request to the `/token` endpoint with the correct verifier. The server validates it and returns an access token, granting the attacker access to the victim’s account.

Protection: from this CVE

  • Upgrade oauthlib: Update to version 3.3.2 or later, which replaces the vulnerable `==` comparison with `hmac.compare_digest()` in both `code_challenge_method_plain` and code_challenge_method_s256.
  • Implement Constant-Time Comparison: If using a custom OAuth 2.0 implementation, ensure all secret comparisons (including PKCE verifiers, HMAC signatures, and session tokens) use a constant-time comparison function. In Python, use hmac.compare_digest().
  • Enforce S256 Method: Where possible, enforce the use of the `S256` code challenge method instead of plain. The `S256` method hashes the verifier before comparison, which inherently mitigates some timing risks, though constant-time comparison should still be used for the final hash comparison.
  • Monitor and Rate-Limit Token Endpoint: Implement rate limiting on the `/token` endpoint to make statistical timing attacks impractical by increasing the number of requests required to achieve statistical significance.
  • Defense-in-Depth: Treat PKCE as one layer of security and combine it with other mitigations such as short-lived authorization codes and strict redirect URI validation to reduce the overall attack surface.

Impact:

Successful exploitation of CVE-2026-49265 allows a remote attacker to obtain a valid access token for a victim’s account, leading to complete account takeover. The attacker can then access all resources and perform all actions authorized by that token, including reading sensitive data, modifying user information, and potentially escalating privileges within the application. The CVSS v4 score is 7 (Medium), reflecting the need for user interaction and the presence of some attack complexity, but the consequences of a successful attack are severe. The vulnerability affects all applications using oauthlib with PKCE enabled and the `plain` code challenge method, or any implementation that relies on non-constant-time comparison for PKCE verification. Organizations using oauthlib in their OAuth 2.0 authorization servers or clients should prioritize upgrading to version 3.3.2 or later to eliminate this timing side-channel.

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

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

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