CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-32597

CVE-2026-32597: Critical Header Parameter Validation Bypass in PyJWT

Alon Barad
Alon Barad
Software Engineer

Mar 25, 2026·7 min read·109 visits

Executive Summary (TL;DR)

PyJWT < 2.12.0 ignores the mandatory 'crit' header in JSON Web Tokens. This fail-open behavior violates RFC 7515 and allows attackers to bypass security extensions like MFA enforcement. Update to 2.12.0 immediately.

PyJWT versions prior to 2.12.0 fail to validate the `crit` (Critical) Header Parameter as mandated by RFC 7515. This allows attackers to bypass security policies enforced via custom JWT extensions by supplying tokens with unsupported critical parameters, which the library silently ignores instead of rejecting.

Vulnerability Overview

PyJWT is a widely deployed Python implementation of the JSON Web Token (JWT) standard. The library is responsible for parsing, verifying, and decoding JWTs, including JSON Web Signatures (JWS). A critical component of the JWS specification, defined in RFC 7515 Section 4.1.11, is the crit (Critical) Header Parameter. This parameter lists extensions that the recipient must understand and process to securely consume the token.

According to the RFC, if a recipient does not support or understand any of the extensions listed in the crit array, the token must be explicitly rejected as invalid. Prior to version 2.12.0, PyJWT did not implement any validation logic for the crit header. The library parsed the header dictionary but ignored the crit array entirely during the verification phase.

This implementation oversight results in a fail-open state. Security-critical extensions designed to enforce additional constraints—such as Proof-of-Possession requirements or multi-factor authentication flags—are silently bypassed by the library. This behavior is classified under CWE-345 (Insufficient Verification of Data Authenticity) and CWE-863 (Incorrect Authorization).

Root Cause Analysis

The vulnerability stems from the absence of a validation routine in the JWS decoding pipeline within jwt/api_jws.py. When PyJWT processes an incoming token, it segments the token into its header, payload, and signature components. The library successfully deserializes the base64url-encoded JSON header into a Python dictionary. However, the verification logic strictly focused on cryptographic signature validation and standard claims (like exp, nbf, and iat), omitting the mandatory structural validation of the JWS headers.

When a token contains a crit array, the specification mandates a strict whitelist approach. The parser must iterate through the crit array, check each string against its internally supported feature set, and immediately halt execution if an unknown extension is encountered. Because PyJWT lacked this iteration and comparison logic, any validly signed token would be accepted, regardless of the unhandled requirements stipulated by the token producer.

This flaw allows a structural desynchronization between token issuers and consumers. An identity provider might issue a token with custom policy constraints embedded in headers, marking them as critical under the assumption that standard-compliant libraries will reject the token if the policies cannot be enforced. PyJWT's failure to respect this contract nullifies the security guarantees provided by the crit specification.

Code Analysis

The remediation introduced in version 2.12.0 adds a dedicated _validate_crit method to the JWS processing logic. The patch explicitly defines a whitelist of supported critical extensions using the _supported_crit set. Currently, only the b64 (RFC 7797) extension is officially supported by the library.

# Added in PyJWT 2.12.0
_supported_crit: set[str] = {"b64"}
 
def _validate_crit(self, headers: dict[str, Any]) -> None:
    crit = headers["crit"]
    if not isinstance(crit, list) or len(crit) == 0:
        raise InvalidTokenError("Invalid 'crit' header: must be a non-empty list")
    for ext in crit:
        if not isinstance(ext, str):
            raise InvalidTokenError("Invalid 'crit' header: values must be strings")
        if ext not in self._supported_crit:
            raise InvalidTokenError(f"Unsupported critical extension: {ext}")
        if ext not in headers:
            raise InvalidTokenError(
                f"Critical extension '{ext}' is missing from headers"
            )

The patched code introduces several strict validation layers. First, it verifies the structural integrity of the crit parameter, ensuring it is a non-empty list. Second, it enforces type constraints by verifying that every element within the list is a string. Third, it implements the core RFC requirement by cross-referencing each element against the _supported_crit whitelist, raising an InvalidTokenError for any unsupported value.

Finally, the logic performs an integrity check to guarantee that the extension declared in the crit array actually exists as a key within the JWS header dictionary. This comprehensive validation ensures compliance with RFC 7515 and prevents the silent bypass of critical security extensions.

Exploitation Methodology

Exploitation requires the attacker to submit a validly signed JWT to a vulnerable application that relies on custom extensions for security enforcement. The attacker crafts a token containing a crit header array that specifies one or more mandatory extensions. These extensions dictate specific processing rules, such as x-enforce-mfa or exp-must-be-verified.

The following proof-of-concept demonstrates how a token with an unsupported critical extension is constructed and subsequently accepted by a vulnerable version of PyJWT. The token is cryptographically signed, meaning the attacker must possess the appropriate signing key or intercept a legitimately signed token from an upstream provider that includes these headers.

import jwt
 
key = "secret"
 
# A token specifying a critical extension 'x-unknown'
header = {
    "alg": "HS256",
    "crit": ["x-unknown"],
    "x-unknown": "must-be-processed"
}
payload = {"sub": "user123", "admin": True}
 
token = jwt.encode(payload, key, algorithm="HS256", headers=header)
 
try:
    # Vulnerable versions return the payload silently.
    decoded = jwt.decode(token, key, algorithms=["HS256"])
    print("Vulnerable: Token with unknown crit extension accepted.")
except jwt.exceptions.InvalidTokenError as e:
    # Patched versions raise an exception.
    print(f"Patched: Token rejected. Error: {e}")

When this token is processed by PyJWT versions prior to 2.12.0, the jwt.decode function successfully returns the payload. The application logic, assuming the underlying library has enforced all constraints specified in the token's header, proceeds with authorization. The failure to reject the token allows the attacker to bypass the intended security policy completely.

Impact Assessment

The vulnerability carries a CVSS v3.1 base score of 7.5 (High), reflected by the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N. The impact is strictly isolated to integrity, as the vulnerability does not directly expose sensitive data or cause resource exhaustion. However, the integrity compromise translates to severe authorization bypasses depending on the surrounding application architecture.

In architectures where an API gateway or identity provider attaches custom constraints to tokens, this vulnerability allows privilege escalation. For example, an identity provider might inject a crit: ["require-hardware-key"] header into tokens for highly privileged operations. Because PyJWT ignores this header, the backend service processes the token as valid without verifying hardware key attestation, granting the attacker elevated access.

The current EPSS score is 0.00009 (0.91st percentile), indicating a low baseline probability of exploitation in the wild. This low score reflects the prerequisite that an attacker must interact with an application specifically utilizing custom crit extensions for security enforcement. The vulnerability does not allow arbitrary signature forgery; it strictly facilitates the bypass of explicit header-based constraints.

Remediation and Mitigation

The primary remediation for this vulnerability is updating PyJWT to version 2.12.0 or higher. This release contains the complete validation logic required to enforce the strict processing rules mandated by RFC 7515. Development teams must update their dependency management manifests (requirements.txt, Pipfile, pyproject.toml) and deploy the patched version across all environments.

For systems where immediate patching is not feasible, developers must implement manual header validation logic before passing the token to jwt.decode(). This involves utilizing jwt.get_unverified_header() to inspect the token structure independently.

The manual validation routine must extract the crit array from the unverified header and reject the token if the array contains any unrecognized parameters. This temporary workaround effectively mimics the patch logic and prevents the silent bypass of critical extensions until the library can be safely upgraded.

Official Patches

jpadillaGitHub Security Advisory
jpadillaFix Commit

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N
EPSS Probability
0.01%
Top 99% most exploited

Affected Systems

PyJWT versions prior to 2.12.0Python backend services relying on custom JWS critical extensions for authorizationAPI gateways utilizing PyJWT for token validation

Affected Versions Detail

Product
Affected Versions
Fixed Version
pyjwt
jpadilla
< 2.12.02.12.0
AttributeDetail
CWE IDCWE-345, CWE-863
Attack VectorNetwork
CVSS v3.1 Score7.5 (High)
EPSS Score0.00009 (0.91%)
ImpactIntegrity Loss (Authorization Bypass)
Exploit StatusProof of Concept Available
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-345
Insufficient Verification of Data Authenticity

Insufficient Verification of Data Authenticity and Incorrect Authorization due to missing structural validation.

Known Exploits & Detection

Security AdvisoryProof of Concept demonstrating the acceptance of unsupported 'crit' headers.

Vulnerability Timeline

Initial disclosure and vendor advisory published (GHSA-752w-5fwx-jx9f).
2026-03-12
PyJWT version 2.12.0 released with the patch.
2026-03-12
CVE-2026-32597 assigned and published to NVD.
2026-03-13

References & Sources

  • [1]GitHub Security Advisory GHSA-752w-5fwx-jx9f
  • [2]Official CVE Record CVE-2026-32597
  • [3]RFC 7515 JSON Web Signature (JWS) - Section 4.1.11

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•less than a minute ago•CVE-2026-56677
8.6

CVE-2026-56677: Unauthenticated Server-Side Request Forgery in 9Router OIDC Test Endpoint

A high-severity security vulnerability exists in 9Router, an AI router and token saver dashboard. When dashboard authentication features are disabled or left in default configurations, the application exposes administrative testing routines directly to the public internet. Unauthenticated network adversaries can exploit the OIDC configuration validation endpoint to initiate arbitrary HTTP requests, routing unauthorized traffic to local loops, adjacent container ports, and cloud resource metadata interfaces.

Amit Schendel
Amit Schendel
0 views•5 min read
•about 1 hour ago•CVE-2026-64849
9.3

CVE-2026-64849: Server-Side Request Forgery (SSRF) in MLflow Webhooks via DNS Rebinding

CVE-2026-64849 is a critical Server-Side Request Forgery (SSRF) vulnerability affecting MLflow tracking servers prior to version 3.15.0. It allows unauthenticated remote attackers to bypass outbound request destination filters using DNS rebinding or HTTP redirects. This exposure risks compromising sensitive cloud infrastructure metadata and internal microservices.

Alon Barad
Alon Barad
2 views•5 min read
•about 2 hours ago•CVE-2026-69146
6.5

CVE-2026-69146: Missing Authorization Bypass in MLflow Basic Authentication Middleware

This technical report details a missing authorization vulnerability (CVE-2026-69146 / GHSA-3p64-6gvh-82v5) affecting the MLflow platform from version 3.13.0 to 3.15.0. When MLflow is configured with the built-in basic-auth plugin, authenticated users can bypass run-level UPDATE authorization checks, enabling unauthorized dataset and model lineage metadata injection.

Alon Barad
Alon Barad
1 views•7 min read
•about 3 hours ago•CVE-2026-69148
7.1

CVE-2026-69148: Broken Object Level Authorization (BOLA) in MLflow Model Registry

MLflow prior to version 3.15.0 fails to perform proper authorization checks when registering model versions, allowing authenticated users with access to a registered model to link and access artifacts from runs and models belonging to other users without authorization.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 4 hours ago•CVE-2026-59893
7.5

CVE-2026-59893: Regular Expression Denial of Service in sqlparse Lexer

A high-severity Regular Expression Denial of Service (ReDoS) vulnerability in the sqlparse Python library prior to version 0.6.0 allows unauthenticated remote attackers to trigger CPU exhaustion and application denial of service via crafted SQL inputs containing unmatched dollar-quoted literals or unclosed multiline comments.

Alon Barad
Alon Barad
4 views•6 min read
•about 5 hours ago•GHSA-FHGH-WQ4Q-R37X
7.8

GHSA-FHGH-WQ4Q-R37X: Remote Code Execution via Sigstore Signature Verification Bypass in uniget CLI

A high-severity logic inversion flaw in the uniget CLI completely bypasses Sigstore cryptographic signature verification on metadata files by default. If an attacker can poison the package metadata cache or repository, they can execute arbitrary OS commands under the privileges of the active user.

Alon Barad
Alon Barad
5 views•5 min read