Oauthlib: Timing Attack Vulnerability in PKCE code_verifier Comparison (CWE-208)
## 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
PYSEC-2026-4114
Primary source · Revision 1
Imported from structured advisory data. Source references identify upstream records or fields; verify affected versions and your deployed configuration.
Security context
Source reference: osv:PYSEC-2026-4114
oauthlib
Source reference: /affected/0/package/name
- Affected versions
- 3.0.0
Source reference:
/affected/0/versions3.0.1Source reference:
/affected/0/versions3.0.2Source reference:
/affected/0/versions3.1.0Source reference:
/affected/0/versions3.1.1Source reference:
/affected/0/versions3.2.0Source reference:
/affected/0/versions3.2.1Source reference:
/affected/0/versions3.2.2Source reference:
/affected/0/versions3.3.0Source reference:
/affected/0/versions3.3.1Source reference:
/affected/0/versions - Fixed versions
- 4.0.0
Source reference:
/affected/0/ranges - Prerequisites
- Not stated in this record
Structured affected-version data
Original package identities and version rules from this source.
[
{
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "3.0.0"
},
{
"fixed": "4.0.0"
}
]
}
],
"package": {
"name": "oauthlib",
"purl": "pkg:pypi/oauthlib",
"ecosystem": "PyPI"
},
"versions": [
"3.0.0",
"3.0.1",
"3.0.2",
"3.1.0",
"3.1.1",
"3.2.0",
"3.2.1",
"3.2.2",
"3.3.0",
"3.3.1"
],
"database_specific": {
"source": "https://github.com/pypa/advisory-database/blob/main/vulns/oauthlib/PYSEC-2026-4114.yaml"
}
}
]- Related CVEs
- CVE-2026-49265
Source reference:
/aliases
Publisher severity
No explicit severity was provided.
- Event
- #62491 · Revision 1
- Added to Heist Feed
- Publisher date