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·146 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

•22 minutes ago•CVE-2026-91129
5.4

CVE-2026-91129: Server-Side Request Forgery in Home Assistant Core IPP Integration

Home Assistant Core prior to version 2026.2.3 is vulnerable to Server-Side Request Forgery (SSRF) via the IPP integration's auto-discovery mechanism. Unauthenticated mDNS advertisements can trigger HTTP requests that follow malicious redirects to loopback interfaces.

Alon Barad
Alon Barad
2 views•7 min read
•about 1 hour ago•CVE-2026-91130
9.3

CVE-2026-91130: DOM-Based Cross-Site Scripting in Home Assistant Statistics Graph Card

CVE-2026-91130 is a critical DOM-based Cross-Site Scripting (XSS) vulnerability in the Home Assistant open-source home automation platform. Prior to version 2026.7.0, the Statistics Graph card rendered series tooltips using raw HTML string interpolation without escaping user-controlled entity friendly names. By abusing this vulnerability, an authenticated user with low-privilege access can inject arbitrary HTML and JavaScript into entity name fields, which executes in the context of an administrative user's browser session upon hovering over a data point on an affected chart.

Alon Barad
Alon Barad
5 views•5 min read
•about 2 hours ago•CVE-2026-58268
7.5

CVE-2026-58268: Denial of Service via Uncontrolled Memory Allocation in emiago/sipgo Stream Parser

A high-severity denial of service vulnerability exists in the emiago/sipgo Go library when parsing stream-based SIP messages. The stream parser fails to validate declared Content-Length header sizes before initiating memory allocations, allowing remote, unauthenticated attackers to trigger process memory exhaustion and application crashes.

Alon Barad
Alon Barad
6 views•6 min read
•about 3 hours ago•CVE-2026-58270
6.5

CVE-2026-58270: Regular Expression Denial of Service (ReDoS) in Sync-in Server

CVE-2026-58270 identifies a Regular Expression Denial of Service (ReDoS) vulnerability in Sync-in Server prior to version 2.4.0. An authenticated attacker can supply a complex regular expression in the pathFilters parameter of the sync diff endpoint. When evaluated, this causes catastrophic backtracking, blocking the single-threaded Node.js event loop and rendering the entire server unresponsive.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 4 hours ago•CVE-2026-56681
7.3

CVE-2026-56681: Authentication Bypass via HTTP Header Spoofing in 9Router

CVE-2026-56681 is a high-severity authentication bypass vulnerability in 9Router, an AI router and token-saving proxy. The vulnerability arises from an improper trust boundary where the application relies on the client-controlled HTTP header X-9r-Real-Ip to determine whether an incoming request originates from a local (loopback) environment. In deployments where requests can reach the Next.js backend directly—bypassing the sanitizing custom-server.js wrapper—a remote, unauthenticated attacker can spoof their origin by supplying an X-9r-Real-Ip: 127.0.0.1 header.

Alon Barad
Alon Barad
7 views•6 min read
•about 5 hours ago•CVE-2026-56682
5.3

CVE-2026-56682: Rate Limiter Lockout Bypass via Header Spoofing in 9Router

A rate limiting bypass vulnerability in 9Router versions before 0.5.6 allows unauthenticated remote attackers to circumvent the login progressive lockout mechanism. By manipulating the client-supplied X-9r-Real-Ip HTTP header, an attacker can rotate the tracking IP address, enabling unthrottled brute-force password guessing against the administrative interface.

Alon Barad
Alon Barad
8 views•7 min read