Skip to content
Heist/ feed
MediumFix available

Oauthlib: Timing Attack Vulnerability in PKCE code_verifier Comparison (CWE-208)

Type: advisorySource: OSV1 source record

## 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

Announced Group revision 1
Original source ↗

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/versions

3.0.1

Source reference: /affected/0/versions

3.0.2

Source reference: /affected/0/versions

3.1.0

Source reference: /affected/0/versions

3.1.1

Source reference: /affected/0/versions

3.2.0

Source reference: /affected/0/versions

3.2.1

Source reference: /affected/0/versions

3.2.2

Source reference: /affected/0/versions

3.3.0

Source reference: /affected/0/versions

3.3.1

Source 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.

Linked CVE context

These ratings describe the referenced vulnerabilities and products. They are not a severity rating for every application using this dependency.

Event
#62491 · Revision 1
Added to Heist Feed
Publisher date
Read the original announcement