Dev.to Security 🔐 Cybersecurity 👁 0 📖 4 min read

CVE-2026-119195: CVE-2026-119195: Quadratic-Time Denial of Service in pyasn1 BER/CER/DER Decoders

CVE-2026-119195: Quadratic-Time Denial of Service in pyasn1 BER/CER/DER Decoders Vulnerability ID: CVE-2026-119195 CVSS Score: 7.5 Published: 2026-10-30 CVE-2026-119195 is an algorithmic complexity vulnerability (CW

CVE-2026-119195: Quadratic-Time Denial of Service in pyasn1 BER/CER/DER Decoders

Vulnerability ID: CVE-2026-119195
CVSS Score: 7.5
Published: 2026-10-30

CVE-2026-119195 is an algorithmic complexity vulnerability (CWE-407) in the pyasn1 library for Python, affecting all versions prior to 0.6.5. When decoding constructed strings or indefinite-length ANY types across BER, CER, and certain DER code paths, the payload decoders repeatedly concatenate incoming fragments onto an immutable bytes object using the += operator. Because Python bytes objects cannot be resized in-place, each fragment iteration allocates a new buffer and copies all previously accumulated bytes, resulting in quadratic O(N^2) time and memory copy complexity. An unauthenticated remote attacker can supply a highly fragmented ASN.1 stream to exhaust CPU cycles and stall application worker threads.

TL;DR

pyasn1 versions prior to 0.6.5 use repeated bytes concatenation (+=) when reassembling constructed strings and indefinite-length ANY encodings. Processing ASN.1 streams with thousands of small fragments triggers quadratic O(N^2) memory copying and CPU exhaustion. Upgrade to pyasn1 0.6.5 or later, which replaces incremental concatenation with linear O(N) list accumulation and b''.join().

⚠️ Exploit Status: POC

Technical Details

  • Vulnerability ID: CVE-2026-119195 (GHSA-9m75-vc3g-4x39)
  • Weakness Class: CWE-407: Inefficient Algorithmic Complexity
  • CVSS v3.1 Score: 7.5 High (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
  • EPSS Score: 0.53% (44.65th Percentile)
  • Affected Component: pyasn1/codec/ber/decoder.py (OctetStringPayloadDecoder, AnyPayloadDecoder)
  • Impact: Unauthenticated Remote Denial of Service (Quadratic CPU & Memory Copy Exhaustion)
  • Patched Version: pyasn1 >= 0.6.5
  • CISA KEV Status: Not Listed

Affected Systems

  • pyasn1 (Python Package Index / PyPI)
  • Red Hat Enterprise Linux / Fedora (python3-pyasn1)
  • Python applications and libraries parsing ASN.1 BER, CER, or DER streams (e.g., pysnmp, pyasn1-modules)
  • pyasn1: < 0.6.5 (Fixed in: 0.6.5)

Code Analysis

Commit: 4ce0079

Replace repeated bytes concatenation with list accumulation and b''.join() in OctetStringPayloadDecoder and AnyPayloadDecoder.

diff --git a/pyasn1/codec/ber/decoder.py b/pyasn1/codec/ber/decoder.py
index a5d3e09..4ce0079 100644
--- a/pyasn1/codec/ber/decoder.py
+++ b/pyasn1/codec/ber/decoder.py
@@ -362,23 +362,20 @@ def valueDecoder(self, substrate, asn1Spec,
         if LOG:
             LOG('assembling constructed serialization')

-        # All inner fragments are of the same type, treat them as octet string
-        substrateFun = self.substrateCollector
-
-        header = b''
+        # Assemble the logical value of each fragment, including nested ones.
+        fragments = []

         original_position = substrate.tell()
         # head = popSubstream(substrate, length)
         while substrate.tell() - original_position < length:
             for component in decodeFun(
-                    substrate, self.protoComponent, substrateFun=substrateFun,
-                    **options):
+                    substrate, self.protoComponent, **options):
                 if isinstance(component, SubstrateUnderrunError):
                     yield component

-            header += component
+            fragments.append(bytes(component))

-        yield self._createComponent(asn1Spec, tagSet, header, **options)
+        yield self._createComponent(asn1Spec, tagSet, b''.join(fragments), **options)

     def indefLenValueDecoder(self, substrate, asn1Spec,
                              tagSet=None, length=None, state=None,
@@ -392,16 +389,13 @@ def indefLenValueDecoder(self, substrate, asn1Spec,

             return

-        # All inner fragments are of the same type, treat them as octet string
-        substrateFun = self.substrateCollector
-
-        header = b''
+        # Assemble the logical value of each fragment, including nested ones.
+        fragments = []

         while True:  # loop over fragments

             for component in decodeFun(
-                    substrate, self.protoComponent, substrateFun=substrateFun,
-                    allowEoo=True, **options):
+                    substrate, self.protoComponent, allowEoo=True, **options):

                 if isinstance(component, SubstrateUnderrunError):
                     yield component
@@ -412,9 +406,9 @@ def indefLenValueDecoder(self, substrate, asn1Spec,
             if component is eoo.endOfOctets:
                 break

-            header += component
+            fragments.append(bytes(component))

-        yield self._createComponent(asn1Spec, tagSet, header, **options)
+        yield self._createComponent(asn1Spec, tagSet, b''.join(fragments), **options)


 class NullPayloadDecoder(AbstractSimplePayloadDecoder):
@@ -1431,6 +1425,8 @@ def indefLenValueDecoder(self, substrate, asn1Spec,
         # All inner fragments are of the same type, treat them as octet string
         substrateFun = self.substrateCollector

+        fragments = [chunk]
+
         while True:  # loop over fragments

             for component in decodeFun(
@@ -1446,7 +1442,9 @@ def indefLenValueDecoder(self, substrate, asn1Spec,
             if component is eoo.endOfOctets:
                 break

-            chunk += component
+            fragments.append(component)
+
+        chunk = b''.join(fragments)

         if substrateFun:
             yield chunk

Mitigation Strategies

  • Upgrade pyasn1 to version 0.6.5 or later across all Python environments and container images.
  • Enforce strict maximum byte-length limits on incoming ASN.1 payloads at the network boundary or reverse proxy layer to cap the maximum number of fragments an attacker can submit.
  • Execute untrusted ASN.1 decoding tasks in process-isolated workers with strict execution timeouts rather than on shared asynchronous event loops.

Remediation Steps:

  1. Audit application dependencies using pip list or pip-audit to identify installed versions of pyasn1 prior to 0.6.5.
  2. Run pip install --upgrade 'pyasn1>=0.6.5' and update dependency lockfiles (requirements.txt, poetry.lock, Pipfile.lock).
  3. Rebuild and redeploy affected application containers or virtual environments.
  4. Verify the installed version at runtime using python3 -c 'import pyasn1; print(pyasn1.__version__)' to confirm it outputs 0.6.5 or higher.

References

Read the full report for CVE-2026-119195 on our website for more details including interactive diagrams and full exploit analysis.

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.