pyasn1 has quadratic-time denial of service in constructed string and indefinite-length ANY decoding
CVE-2026-119195 · GHSA-9m75-vc3g-4x39 · published 30 Oct 2026
How serious is it
- Severity: high, CVSS score 7.5 out of 10.
- No exploit prediction (EPSS) score yet.
- Not on the CISA list of exploited vulnerabilities.
- No public exploit in Exploit-DB.
Is your app affected by CVE-2026-119195?
Paste this prompt into Claude Code, Cursor or any AI coding tool: it runs a free Shippable scan of your project and fixes what it finds. Built with Lovable, Bolt or v0? Scan your live app. Or upload your package file.
Who is affected
pyasn1(PyPI) <= 0.6.4
How to check
- Run
pip show pyasn1in your project to see the installed version, including copies pulled in by other packages. - Or paste your lockfile into the checker: it lists every package with a known vulnerability, this one included.
- Or run
npx shippable-dev scan localhost:3000in your project folder. It reads your lockfile and flags this vulnerability along with every other known one.
How to fix
Copies a prompt for Claude Code, Cursor or Codex: it checks your lockfiles for this and upgrades it.
- Upgrade
pyasn1to 0.6.5 or later, commit the lockfile and redeploy. - If a vulnerable version was live, check your logs and rotate the secrets that server could read.
The advisory
## Summary
In pyasn1 0.6.4 and earlier, decoding a constructed OCTET STRING or character string made of many fragments can spend disproportionate CPU time repeatedly copying the accumulated value. A separate indefinite-length `ANY` path has the same problem while collecting the encoded components. The work grows roughly quadratically with the number of fixed-size fragments, although the input and decoded value grow linearly. An application that lets an attacker supply such ASN.1 input to an affected decoder can suffer CPU exhaustion.
The affected string paths are available in BER and CER. The DER decoder also accepts certain *non-DER* constructed strings: a definite-length constructed OCTET STRING when an `asn1Spec` selects `univ.OctetString`, and constructed character strings such as UTF8String even without a schema. Indefinite-length `ANY` is affected in BER and CER when an `asn1Spec` selects `univ.Any`; DER rejects indefinite lengths.
This is a distinct decoder path from the OBJECT IDENTIFIER/RELATIVE-OID accumulation addressed by [CVE-2026-59885](https://github.com/advisories/GHSA-8ppf-4f7h-5ppj). It has the same complexity class, but the OID fix in 0.6.4 did not change these string or `ANY` loops.
## Technical details
In the [v0.6.4 BER decoder](https://github.com/pyasn1/pyasn1/blob/v0.6.4/pyasn1/codec/ber/decoder.py), `OctetStringPayloadDecoder` appends each decoded fragment to a growing `bytes` value with `header += component` in both its [definite-length](https://github.com/pyasn1/pyasn1/blob/v0.6.4/pyasn1/codec/ber/decoder.py#L338-L351) and [indefinite-length](https://github.com/pyasn1/pyasn1/blob/v0.6.4/pyasn1/codec/ber/decoder.py#L368-L387) constructed forms. [`AnyPayloadDecoder.indefLenValueDecoder`](https://github.com/pyasn1/pyasn1/blob/v0.6.4/pyasn1/codec/ber/decoder.py#L1403-L1430) similarly uses `chunk += component`. In the exercised paths, each concatenation copies an increasingly large prefix. For `N` fixed-size fragments, the total copied data grows with `1 + 2 + ... + N`, or O(N²).
The OCTET STRING decoder is also the base class of the decoders for UTF8String, NumericString, PrintableString, TeletexString, VideotexString, IA5String, GraphicString, VisibleString, GeneralString, UniversalString, BMPString, ObjectDescriptor, GeneralizedTime, and UTCTime. These types inherit the same constructed-string reassembly path.
The [DER decoder's OCTET STRING restriction](https://github.com/pyasn1/pyasn1/blob/v0.6.4/pyasn1/codec/der/decoder.py#L15-L49) replaces the tag-driven decoder, but its schema-driven `TYPE_MAP` retains the BER-derived decoder. Thus `der.decode(data)` rejects a constructed OCTET STRING, while `der.decode(data, asn1Spec=univ.OctetString())` accepts its definite-length form and reaches the accumulation loop. DER does not replace the inherited character-string decoders, so a constructed UTF8String is also accepted without `asn1Spec`. These inputs violate [X.690's DER string-encoding rule](https://www.itu.int/rec/T-REC-X.690-202102-I/en) and should not be described as valid DER encodings.
The original short-fragment, definite-length OCTET STRING reproducer is valid BER. The CER decoder accepts it, but it is not a conforming CER string encoding: X.690 requires an indefinite-length outer constructed string and 1,000 contents octets per fragment except possibly the last. A conforming CER-shaped constructed OCTET STRING with those fragment sizes also reaches the loop and shows quadratic growth. The indefinite-length `ANY` reproducer below can represent a CER `SEQUENCE OF OCTET STRING` and reaches the separate `ANY` loop when decoded with an `ANY` schema.
The decoder's eight-octet length-field limit and nesting-depth limit do not bound the number of sibling fragments in these examples. The BER reproducer below uses only a three-octet outer length field; all fragments have shallow nesting. There is no per-message fragment-count cap in v0.6.4.
## Impact
If an application passes attacker-controlled ASN.1 to the affected `decode()` or `StreamingDecoder` path without an adequate input or resource limit, a megabyte-scale value can occupy a decoding worker for seconds. Repeated inputs can exhaust available CPU. Whether this is reachable before authentication, or through a particular protocol, depends on the application; the library finding alone does not establish those conditions. No confidentiality or integrity impact is claimed.
## Severity assessment (CVSS v3.1)
The 7.5 Base score assumes a reasonable application that automatically decodes attacker-supplied ASN.1 from unauthenticated network input. Valid BER and conforming CER inputs trigger the string-reassembly issue without special conditions, privileges, or user interaction. Repeated crafted inputs could occupy all available decoder workers and deny service while the attack continues. No confidentiality or integrity impact is demonstrated. This library-level score does not assert that every adopter has such an endpoint or loses all service; deployment-specific input limits and architecture may change the score. See [FIRST's library-scoring guidance](https://www.first.org/cvss/v3-1/user-guide).
On the official v0.6.4 tag, local CPU-time measurements with CPython 3.14.8 on macOS arm64 gave the following results. Times vary by machine and Python runtime; the input-size scaling is the relevant observation. “Fixed” means the local 0.6.5 decoder fix applied to the same inputs.
| Decoder path and input | Fragments | v0.6.4 CPU | Fixed CPU |
| --- | ---: | ---: | ---: |
| BER constructed OCTET STRING, 0.40 MB | 100,000 × 2 payload bytes | 0.340 s | 0.160 s |
| BER constructed OCTET STRING, 0.80 MB | 200,000 × 2 payload bytes | 0.886 s | 0.312 s |
| BER constructed OCTET STRING, 1.60 MB | 400,000 × 2 payload bytes | 2.738 s | 0.623 s |
| BER indefinite `ANY`, 0.30 MB | 100,000 × 1 payload byte | 0.459 s | 0.206 s |
| BER indefinite `ANY`, 0.60 MB | 200,000 × 1 payload byte | 1.245 s | 0.412 s |
| BER indefinite…
Check your whole app
Dependencies are only half of it. Free and read-only: before you push, run npx shippable-dev scan localhost:3000 in your project folder, no account needed. For your live app, you prove it's yours with a one-line tag first.
References
- github.com/pyasn1/pyasn1/security/advisories/GHSA-9m75-vc3g-4x39
- nvd.nist.gov/vuln/detail/CVE-2026-119195
- github.com/pyasn1/pyasn1/pull/132
- github.com/pyasn1/pyasn1/commit/4ce00797c594b59c1fd6b86d9ebc3ba87b7ec9f9
- github.com/pyasn1/pyasn1/releases/tag/v0.6.5
- github.com/advisories/GHSA-9m75-vc3g-4x39
- github.com/pyasn1/pyasn1
Merged from GitHub Advisory Database, OSV. Last updated 31 Oct 2026. All vulnerabilities · RSS · JSON