GitHub Advisoryadvisory · PyPI
GHSA-xpv3-w29h-x7cv Oauthlib: Timing Attack Vulnerability in PKCE code_verifier Comparison (CWE-208)
MEDIUM
Official page ↗
- Aliases
- CVE-2026-49265
- Ecosystem
- PyPI
- Packages
- oauthlib
- Severity
- Moderate
- CVSS vector
- CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:H/I:H/A:N
- Weaknesses
- CWE-208
- Reviewed
- 2026-09-29
Affected packages
• PyPI oauthlib: >= 3.0.0, < 4.0.0 → fixed in 4.0.0
Description
Summary
A timing side-channel vulnerability exists in the PKCE (RFC 7636) implementation
of the Authorization Code Grant flow. The `code_challenge_method_plain` function
uses Python's standard `==` operator for string comparison instead of a
constant-time comparison function, potentially allowing timing-based attacks.
Affected Component
• File: `oauthlib/oauth2/rfc6749/grant_types/authorization_code.py`
• Functions: `code_challenge_method_plain`, `code_challenge_method_s256`
• Vulnerability Type: CWE-208 (Observable Timing Discrepancy)
Technical Details
Python's `==` operator uses short-circuit evaluation when comparing strings:
1. Returns `False` immediately if lengths differ
2. Compares characters left-to-right, stopping at first mismatch
This means comparison time varies linearly with the length of the common prefix
between the attacker-supplied verifier and the stored challenge, creating a
measurable timing oracle.
Proof of Concept
Tested locally against oauthlib source (network jitter eliminated to isolate
pure Python execution time):
| Input | Result | Time (10M iterations) |
|---|---|---|
| Wrong first char (`B` + `A`*49) | Fast reject | 0.34106s |
| 49 chars correct (`A`*49 + `B`) | Deep compare | 0.37847s |
| Difference | | 0.03741s |
The ~37ms delta over 10M iterations corresponds to nanosecond-level differences
per call, which are statistically exploitable under controlled conditions.
Attack Scenario
1. Attacker intercepts `authorization_code` via Custom URI Scheme Hijacking
2. PKCE blocks token request — attacker lacks `code_verifier`
3. Attacker sends repeated requests to `/token` endpoint measuring response times
4. Using timing oracle, attacker recovers `code_verifier` character by character
5. Attacker obtains Access Token → Account Takeover
> Note: Practical exploitability is limited due to the single-use nature of
> authorization codes and real-world network noise. However, the vulnerable
> pattern should be corrected as a defense-in-depth measure.
Recommended Fix
Replace `==` with `hmac.compare_digest()` for constant-time comparison:
cr: Elvin Latifli
Related
Alias · CVE (1)
- CVE-2026-49265 OAuthLib is an implementation of the OAuth request-signing logic for Python 3.6+. vulnerability
Weakness · CWE (1)
- CWE-208 Observable Timing Discrepancy weakness
References
- https://github.com/oauthlib/oauthlib/security/advisories/GHSA-xpv3-w29h-x7cv web
- https://nvd.nist.gov/vuln/detail/CVE-2026-49265 advisory
- https://github.com/oauthlib/oauthlib/pull/963 web
- https://github.com/oauthlib/oauthlib/commit/40b0ab56da3682c2484a4b78bbff309f8025d950 web
- https://github.com/oauthlib/oauthlib package
- https://github.com/pypa/advisory-database/tree/main/vulns/oauthlib/PYSEC-2026-4114.yaml web