CVE-2026-119434 (GCVE-0-2026-119434)

Vulnerability from cvelistv5 – Published: 2026-11-05 20:15 – Updated: 2026-11-05 20:45
VLAI
Title
Decompression bomb in ezstd:decompress_using_ddict/2 allows BEAM memory exhaustion via unbounded output buffer
Summary
Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to ezstd:decompress_using_ddict/2 to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size. zstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads the frame's declared content size with ZSTD_getFrameContentSize and passes it directly to enif_make_new_binary, without the 1 GiB MAX_BUFFER_SIZE check that ezstd:decompress/1 applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by ezstd:decompress/1 but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process. This issue affects ezstd: from 1.0.5 before 1.2.5.
SSVC
Exploitation: none Automatable: no Technical Impact: partial
CISA Coordinator · CISA-ADP (v2.0.3)
Decision recorded 2026-11-05 20:45 UTC
CWE
  • CWE-409 - Improper Handling of Highly Compressed Data (Data Amplification)
Assigner
EEF CNA under the mitre root
CNA scorecard A 97/100 over 351 records in the last 180 days details
Impacted products
Vendor Product Version CPE status
silviucpp ezstd Affected: 1.0.5 , < 1.2.5 (semver)
    cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*
Create a notification for this product.
silviucpp ezstd Affected: 6730128b1d35eca02a2028671421471ff651f423 , < e34f4a4f6dc18d990d1cece2d5fceef8e934a195 (git)
    cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*
Create a notification for this product.
Show details on NVD website

{
  "containers": {
    "adp": [
      {
        "metrics": [
          {
            "cvssV3_1": {
              "attackComplexity": "LOW",
              "attackVector": "LOCAL",
              "availabilityImpact": "HIGH",
              "baseScore": 6.2,
              "baseSeverity": "MEDIUM",
              "confidentialityImpact": "NONE",
              "integrityImpact": "NONE",
              "privilegesRequired": "NONE",
              "scope": "UNCHANGED",
              "userInteraction": "NONE",
              "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
              "version": "3.1"
            }
          },
          {
            "other": {
              "content": {
                "id": "CVE-2026-119434",
                "options": [
                  {
                    "Exploitation": "none"
                  },
                  {
                    "Automatable": "no"
                  },
                  {
                    "Technical Impact": "partial"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2026-11-05T20:45:27.204341Z",
                "version": "2.0.3"
              },
              "type": "ssvc"
            }
          }
        ],
        "providerMetadata": {
          "dateUpdated": "2026-11-05T20:45:33.490Z",
          "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
          "shortName": "CISA-ADP"
        },
        "title": "CISA ADP Vulnrichment"
      }
    ],
    "cna": {
      "affected": [
        {
          "collectionURL": "https://repo.hex.pm",
          "cpes": [
            "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "ezstd_nif",
            "ezstd"
          ],
          "packageName": "ezstd",
          "packageURL": "pkg:hex/ezstd",
          "product": "ezstd",
          "programFiles": [
            "c_src/ezstd_nif.cc",
            "src/ezstd_nif.erl",
            "src/ezstd.erl"
          ],
          "programRoutines": [
            {
              "name": "zstd_nif_decompress_using_ddict"
            },
            {
              "name": "ezstd_nif:decompress_using_ddict/2"
            },
            {
              "name": "ezstd:decompress_using_ddict/2"
            }
          ],
          "repo": "https://github.com/silviucpp/ezstd",
          "vendor": "silviucpp",
          "versions": [
            {
              "lessThan": "1.2.5",
              "status": "affected",
              "version": "1.0.5",
              "versionType": "semver"
            }
          ]
        },
        {
          "collectionURL": "https://github.com",
          "cpes": [
            "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*"
          ],
          "defaultStatus": "unaffected",
          "modules": [
            "ezstd_nif",
            "ezstd"
          ],
          "packageName": "silviucpp/ezstd",
          "packageURL": "pkg:github/silviucpp/ezstd",
          "product": "ezstd",
          "programFiles": [
            "c_src/ezstd_nif.cc",
            "src/ezstd_nif.erl",
            "src/ezstd.erl"
          ],
          "programRoutines": [
            {
              "name": "zstd_nif_decompress_using_ddict"
            },
            {
              "name": "ezstd_nif:decompress_using_ddict/2"
            },
            {
              "name": "ezstd:decompress_using_ddict/2"
            }
          ],
          "repo": "https://github.com/silviucpp/ezstd",
          "vendor": "silviucpp",
          "versions": [
            {
              "lessThan": "e34f4a4f6dc18d990d1cece2d5fceef8e934a195",
              "status": "affected",
              "version": "6730128b1d35eca02a2028671421471ff651f423",
              "versionType": "git"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "1.2.5",
                  "versionStartIncluding": "1.0.5",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ],
          "operator": "AND"
        }
      ],
      "credits": [
        {
          "lang": "en",
          "type": "finder",
          "value": "Oz Kaiser"
        },
        {
          "lang": "en",
          "type": "reporter",
          "value": "Oz Kaiser"
        },
        {
          "lang": "en",
          "type": "remediation developer",
          "value": "Silviu Caragea"
        },
        {
          "lang": "en",
          "type": "coordinator",
          "value": "Jonatan M\u00e4nnchen / EEF"
        }
      ],
      "dateAssigned": "2026-11-04T17:02:50.000Z",
      "descriptions": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eImproper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ezstd_nif_decompress_using_ddict\u003c/code\u003e in \u003ccode\u003ec_src/ezstd_nif.cc\u003c/code\u003e reads the frame\u0027s declared content size with \u003ccode\u003eZSTD_getFrameContentSize\u003c/code\u003e and passes it directly to \u003ccode\u003eenif_make_new_binary\u003c/code\u003e, without the 1 GiB \u003ccode\u003eMAX_BUFFER_SIZE\u003c/code\u003e check that \u003ccode\u003eezstd:decompress/1\u003c/code\u003e applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by \u003ccode\u003eezstd:decompress/1\u003c/code\u003e but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\u003c/p\u003e\n\u003cp\u003eThis issue affects ezstd: from 1.0.5 before 1.2.5.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to `ezstd:decompress_using_ddict/2` to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\n\n`zstd_nif_decompress_using_ddict` in `c_src/ezstd_nif.cc` reads the frame\u0027s declared content size with `ZSTD_getFrameContentSize` and passes it directly to `enif_make_new_binary`, without the 1 GiB `MAX_BUFFER_SIZE` check that `ezstd:decompress/1` applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by `ezstd:decompress/1` but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\n\nThis issue affects ezstd: from 1.0.5 before 1.2.5."
            }
          ],
          "value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to ezstd:decompress_using_ddict/2 to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\n\nzstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads the frame\u0027s declared content size with ZSTD_getFrameContentSize and passes it directly to enif_make_new_binary, without the 1 GiB MAX_BUFFER_SIZE check that ezstd:decompress/1 applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by ezstd:decompress/1 but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\n\nThis issue affects ezstd: from 1.0.5 before 1.2.5."
        }
      ],
      "impacts": [
        {
          "capecId": "CAPEC-130",
          "descriptions": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003eAn attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "An attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor."
                }
              ],
              "value": "An attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor."
            }
          ]
        }
      ],
      "metrics": [
        {
          "cvssV4_0": {
            "Automatable": "NOT_DEFINED",
            "Recovery": "NOT_DEFINED",
            "Safety": "NOT_DEFINED",
            "attackComplexity": "LOW",
            "attackRequirements": "NONE",
            "attackVector": "LOCAL",
            "baseScore": 6.9,
            "baseSeverity": "MEDIUM",
            "privilegesRequired": "NONE",
            "providerUrgency": "NOT_DEFINED",
            "subAvailabilityImpact": "NONE",
            "subConfidentialityImpact": "NONE",
            "subIntegrityImpact": "NONE",
            "userInteraction": "NONE",
            "valueDensity": "NOT_DEFINED",
            "vectorString": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
            "version": "4.0",
            "vulnAvailabilityImpact": "HIGH",
            "vulnConfidentialityImpact": "NONE",
            "vulnIntegrityImpact": "NONE",
            "vulnerabilityResponseEffort": "NOT_DEFINED"
          },
          "format": "CVSS",
          "scenarios": [
            {
              "lang": "en",
              "value": "GENERAL"
            }
          ]
        }
      ],
      "problemTypes": [
        {
          "descriptions": [
            {
              "cweId": "CWE-409",
              "description": "CWE-409 Improper Handling of Highly Compressed Data (Data Amplification)",
              "lang": "en",
              "type": "CWE"
            }
          ]
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-11-05T20:15:56.311Z",
        "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "shortName": "EEF"
      },
      "references": [
        {
          "name": "ezstd v1.2.5 release notes",
          "tags": [
            "release-notes",
            "related"
          ],
          "url": "https://github.com/silviucpp/ezstd/releases/tag/v1.2.5"
        },
        {
          "name": "EEF CNA record for CVE-2026-119434",
          "tags": [
            "related",
            "third-party-advisory"
          ],
          "url": "https://cna.erlef.org/cves/CVE-2026-119434.html"
        },
        {
          "name": "OSV record EEF-CVE-2026-119434",
          "tags": [
            "related"
          ],
          "url": "https://osv.dev/vulnerability/EEF-CVE-2026-119434"
        },
        {
          "name": "Introducing commit 6730128 in silviucpp/ezstd",
          "tags": [
            "related"
          ],
          "url": "https://github.com/silviucpp/ezstd/commit/6730128b1d35eca02a2028671421471ff651f423"
        },
        {
          "name": "Fix commit e34f4a4 in silviucpp/ezstd",
          "tags": [
            "patch"
          ],
          "url": "https://github.com/silviucpp/ezstd/commit/e34f4a4f6dc18d990d1cece2d5fceef8e934a195"
        }
      ],
      "source": {
        "discovery": "EXTERNAL"
      },
      "title": "Decompression bomb in ezstd:decompress_using_ddict/2 allows BEAM memory exhaustion via unbounded output buffer",
      "workarounds": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003eReplace calls to \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e with the streaming API: create a context with \u003ccode\u003eezstd:create_decompression_context/1\u003c/code\u003e using a small output buffer, attach the dictionary with \u003ccode\u003eezstd:select_ddict/2\u003c/code\u003e, and decompress with \u003ccode\u003eezstd:decompress_streaming/2\u003c/code\u003e. The streaming path decompresses into the caller-sized buffer and gives up with \u003ccode\u003e{error, decompressor_stuck}\u003c/code\u003e after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "Replace calls to `ezstd:decompress_using_ddict/2` with the streaming API: create a context with `ezstd:create_decompression_context/1` using a small output buffer, attach the dictionary with `ezstd:select_ddict/2`, and decompress with `ezstd:decompress_streaming/2`. The streaming path decompresses into the caller-sized buffer and gives up with `{error, decompressor_stuck}` after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload."
            }
          ],
          "value": "Replace calls to ezstd:decompress_using_ddict/2 with the streaming API: create a context with ezstd:create_decompression_context/1 using a small output buffer, attach the dictionary with ezstd:select_ddict/2, and decompress with ezstd:decompress_streaming/2. The streaming path decompresses into the caller-sized buffer and gives up with {error, decompressor_stuck} after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload."
        }
      ],
      "x_proofOfConcept": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003col\u003e\n\u003cli\u003eBuild ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\u003c/li\u003e\n\u003cli\u003eCreate any decompression dictionary with \u003ccode\u003eezstd:create_ddict/1\u003c/code\u003e; its content does not matter because the frame carries no dictionary ID.\u003c/li\u003e\n\u003cli\u003eConstruct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header \u003ccode\u003e0x02 0x00 0x10\u003c/code\u003e followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\u003c/li\u003e\n\u003cli\u003eCall \u003ccode\u003eezstd:decompress/1\u003c/code\u003e on the frame: it returns \u003ccode\u003e{error, \u0026lt;\u0026lt;\"frame too large or invalid\"\u0026gt;\u0026gt;}\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eCall \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\u003c/li\u003e\n\u003cli\u003eRepeat on 1.2.5: the call returns \u003ccode\u003e{error, \u0026lt;\u0026lt;\"frame too large or invalid\"\u0026gt;\u0026gt;}\u003c/code\u003e and the VM continues.\u003c/li\u003e\n\u003c/ol\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "1. Build ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\n2. Create any decompression dictionary with `ezstd:create_ddict/1`; its content does not matter because the frame carries no dictionary ID.\n3. Construct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header `0x02 0x00 0x10` followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\n4. Call `ezstd:decompress/1` on the frame: it returns `{error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}`.\n5. Call `ezstd:decompress_using_ddict/2` on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\n6. Repeat on 1.2.5: the call returns `{error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}` and the VM continues."
            }
          ],
          "value": "* Build ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\n* Create any decompression dictionary with ezstd:create_ddict/1; its content does not matter because the frame carries no dictionary ID.\n* Construct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header 0x02 0x00 0x10 followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\n* Call ezstd:decompress/1 on the frame: it returns {error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}.\n* Call ezstd:decompress_using_ddict/2 on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\n* Repeat on 1.2.5: the call returns {error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e} and the VM continues."
        }
      ],
      "x_technicalAnalysis": [
        {
          "lang": "en",
          "supportingMedia": [
            {
              "base64": false,
              "type": "text/html",
              "value": "\u003cp\u003e\u003cstrong\u003e1. Declared size is attacker controlled.\u003c/strong\u003e A zstd frame header carries an optional Frame Content Size field. \u003ccode\u003ezstd_nif_decompress_using_ddict\u003c/code\u003e in \u003ccode\u003ec_src/ezstd_nif.cc\u003c/code\u003e reads it with \u003ccode\u003eZSTD_getFrameContentSize\u003c/code\u003e and rejects only the two sentinel values \u003ccode\u003eZSTD_CONTENTSIZE_UNKNOWN\u003c/code\u003e and \u003ccode\u003eZSTD_CONTENTSIZE_ERROR\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e2. Unbounded allocation.\u003c/strong\u003e The size is passed directly to \u003ccode\u003eenif_make_new_binary\u003c/code\u003e, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling \u003ccode\u003ezstd_nif_decompress\u003c/code\u003e rejects any declared size above \u003ccode\u003eMAX_BUFFER_SIZE\u003c/code\u003e (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e3. Amplification.\u003c/strong\u003e A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. \u003ccode\u003eZSTD_decompress_usingDDict\u003c/code\u003e then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception.\u003c/p\u003e"
            },
            {
              "base64": false,
              "type": "text/markdown",
              "value": "**1. Declared size is attacker controlled.** A zstd frame header carries an optional Frame Content Size field. `zstd_nif_decompress_using_ddict` in `c_src/ezstd_nif.cc` reads it with `ZSTD_getFrameContentSize` and rejects only the two sentinel values `ZSTD_CONTENTSIZE_UNKNOWN` and `ZSTD_CONTENTSIZE_ERROR`.\n\n**2. Unbounded allocation.** The size is passed directly to `enif_make_new_binary`, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling `zstd_nif_decompress` rejects any declared size above `MAX_BUFFER_SIZE` (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\n\n**3. Amplification.** A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. `ZSTD_decompress_usingDDict` then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception."
            }
          ],
          "value": "1. Declared size is attacker controlled. A zstd frame header carries an optional Frame Content Size field. zstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads it with ZSTD_getFrameContentSize and rejects only the two sentinel values ZSTD_CONTENTSIZE_UNKNOWN and ZSTD_CONTENTSIZE_ERROR.\n\n2. Unbounded allocation. The size is passed directly to enif_make_new_binary, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling zstd_nif_decompress rejects any declared size above MAX_BUFFER_SIZE (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\n\n3. Amplification. A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. ZSTD_decompress_usingDDict then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception."
        }
      ]
    }
  },
  "cveMetadata": {
    "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
    "assignerShortName": "EEF",
    "cveId": "CVE-2026-119434",
    "datePublished": "2026-11-05T20:15:56.311Z",
    "dateReserved": "2026-10-30T10:30:01.015Z",
    "dateUpdated": "2026-11-05T20:45:33.490Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2",
  "vulnerability-lookup:meta": {
    "epss": {
      "cve": "CVE-2026-119434",
      "date": "2026-11-07",
      "epss": "0.00178",
      "percentile": "0.07387"
    },
    "nvd": {
      "cve": {
        "affected": [
          {
            "affectedData": [
              {
                "collectionURL": "https://repo.hex.pm",
                "cpes": [
                  "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*"
                ],
                "defaultStatus": "unaffected",
                "modules": [
                  "ezstd_nif",
                  "ezstd"
                ],
                "packageName": "ezstd",
                "packageURL": "pkg:hex/ezstd",
                "product": "ezstd",
                "programFiles": [
                  "c_src/ezstd_nif.cc",
                  "src/ezstd_nif.erl",
                  "src/ezstd.erl"
                ],
                "programRoutines": [
                  {
                    "name": "zstd_nif_decompress_using_ddict"
                  },
                  {
                    "name": "ezstd_nif:decompress_using_ddict/2"
                  },
                  {
                    "name": "ezstd:decompress_using_ddict/2"
                  }
                ],
                "repo": "https://github.com/silviucpp/ezstd",
                "vendor": "silviucpp",
                "versions": [
                  {
                    "lessThan": "1.2.5",
                    "status": "affected",
                    "version": "1.0.5",
                    "versionType": "semver"
                  }
                ]
              },
              {
                "collectionURL": "https://github.com",
                "cpes": [
                  "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*"
                ],
                "defaultStatus": "unaffected",
                "modules": [
                  "ezstd_nif",
                  "ezstd"
                ],
                "packageName": "silviucpp/ezstd",
                "packageURL": "pkg:github/silviucpp/ezstd",
                "product": "ezstd",
                "programFiles": [
                  "c_src/ezstd_nif.cc",
                  "src/ezstd_nif.erl",
                  "src/ezstd.erl"
                ],
                "programRoutines": [
                  {
                    "name": "zstd_nif_decompress_using_ddict"
                  },
                  {
                    "name": "ezstd_nif:decompress_using_ddict/2"
                  },
                  {
                    "name": "ezstd:decompress_using_ddict/2"
                  }
                ],
                "repo": "https://github.com/silviucpp/ezstd",
                "vendor": "silviucpp",
                "versions": [
                  {
                    "lessThan": "e34f4a4f6dc18d990d1cece2d5fceef8e934a195",
                    "status": "affected",
                    "version": "6730128b1d35eca02a2028671421471ff651f423",
                    "versionType": "git"
                  }
                ]
              }
            ],
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db"
          }
        ],
        "cveTags": [],
        "descriptions": [
          {
            "lang": "en",
            "value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to ezstd:decompress_using_ddict/2 to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\n\nzstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads the frame\u0027s declared content size with ZSTD_getFrameContentSize and passes it directly to enif_make_new_binary, without the 1 GiB MAX_BUFFER_SIZE check that ezstd:decompress/1 applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by ezstd:decompress/1 but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\n\nThis issue affects ezstd: from 1.0.5 before 1.2.5."
          }
        ],
        "id": "CVE-2026-119434",
        "lastModified": "2026-11-05T21:18:41.210",
        "metrics": {
          "cvssMetricV31": [
            {
              "cvssData": {
                "attackComplexity": "LOW",
                "attackVector": "LOCAL",
                "availabilityImpact": "HIGH",
                "baseScore": 6.2,
                "baseSeverity": "MEDIUM",
                "confidentialityImpact": "NONE",
                "integrityImpact": "NONE",
                "privilegesRequired": "NONE",
                "scope": "UNCHANGED",
                "userInteraction": "NONE",
                "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
                "version": "3.1"
              },
              "exploitabilityScore": 2.5,
              "impactScore": 3.6,
              "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
              "type": "Secondary"
            }
          ],
          "cvssMetricV40": [
            {
              "cvssData": {
                "Automatable": "NOT_DEFINED",
                "Recovery": "NOT_DEFINED",
                "Safety": "NOT_DEFINED",
                "attackComplexity": "LOW",
                "attackRequirements": "NONE",
                "attackVector": "LOCAL",
                "availabilityRequirement": "NOT_DEFINED",
                "baseScore": 6.9,
                "baseSeverity": "MEDIUM",
                "confidentialityRequirement": "NOT_DEFINED",
                "exploitMaturity": "NOT_DEFINED",
                "integrityRequirement": "NOT_DEFINED",
                "modifiedAttackComplexity": "NOT_DEFINED",
                "modifiedAttackRequirements": "NOT_DEFINED",
                "modifiedAttackVector": "NOT_DEFINED",
                "modifiedPrivilegesRequired": "NOT_DEFINED",
                "modifiedSubAvailabilityImpact": "NOT_DEFINED",
                "modifiedSubConfidentialityImpact": "NOT_DEFINED",
                "modifiedSubIntegrityImpact": "NOT_DEFINED",
                "modifiedUserInteraction": "NOT_DEFINED",
                "modifiedVulnAvailabilityImpact": "NOT_DEFINED",
                "modifiedVulnConfidentialityImpact": "NOT_DEFINED",
                "modifiedVulnIntegrityImpact": "NOT_DEFINED",
                "privilegesRequired": "NONE",
                "providerUrgency": "NOT_DEFINED",
                "subAvailabilityImpact": "NONE",
                "subConfidentialityImpact": "NONE",
                "subIntegrityImpact": "NONE",
                "userInteraction": "NONE",
                "valueDensity": "NOT_DEFINED",
                "vectorString": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
                "version": "4.0",
                "vulnAvailabilityImpact": "HIGH",
                "vulnConfidentialityImpact": "NONE",
                "vulnIntegrityImpact": "NONE",
                "vulnerabilityResponseEffort": "NOT_DEFINED"
              },
              "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
              "type": "Secondary"
            }
          ],
          "ssvcV203": [
            {
              "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
              "ssvcData": {
                "id": "CVE-2026-119434",
                "options": [
                  {
                    "exploitation": "none"
                  },
                  {
                    "automatable": "no"
                  },
                  {
                    "technicalImpact": "partial"
                  }
                ],
                "role": "CISA Coordinator",
                "timestamp": "2026-11-05T20:45:27.204341Z",
                "version": "2.0.3"
              }
            }
          ]
        },
        "published": "2026-11-05T21:18:41.210",
        "references": [
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://cna.erlef.org/cves/CVE-2026-119434.html"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://github.com/silviucpp/ezstd/commit/6730128b1d35eca02a2028671421471ff651f423"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://github.com/silviucpp/ezstd/commit/e34f4a4f6dc18d990d1cece2d5fceef8e934a195"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://github.com/silviucpp/ezstd/releases/tag/v1.2.5"
          },
          {
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "url": "https://osv.dev/vulnerability/EEF-CVE-2026-119434"
          }
        ],
        "sourceIdentifier": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "vulnStatus": "Received",
        "weaknesses": [
          {
            "description": [
              {
                "lang": "en",
                "value": "CWE-409"
              }
            ],
            "source": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "type": "Secondary"
          }
        ]
      }
    },
    "redhat_vex": {
      "current_release_date": "2026-11-06T07:10:07+00:00",
      "cve": "CVE-2026-119434",
      "id": "CVE-2026-119434",
      "initial_release_date": "2026-11-05T20:15:56.311000+00:00",
      "product_status:known_not_affected": "1",
      "source": "Red Hat CSAF VEX",
      "status": "final",
      "title": "ezstd: ezstd: Denial of Service via memory exhaustion during decompression",
      "url": "https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-119434.json",
      "version": "3"
    },
    "vulnrichment": {
      "containers": {
        "adp": [
          {
            "metrics": [
              {
                "cvssV3_1": {
                  "attackComplexity": "LOW",
                  "attackVector": "LOCAL",
                  "availabilityImpact": "HIGH",
                  "baseScore": 6.2,
                  "baseSeverity": "MEDIUM",
                  "confidentialityImpact": "NONE",
                  "integrityImpact": "NONE",
                  "privilegesRequired": "NONE",
                  "scope": "UNCHANGED",
                  "userInteraction": "NONE",
                  "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
                  "version": "3.1"
                }
              },
              {
                "other": {
                  "content": {
                    "id": "CVE-2026-119434",
                    "options": [
                      {
                        "Exploitation": "none"
                      },
                      {
                        "Automatable": "no"
                      },
                      {
                        "Technical Impact": "partial"
                      }
                    ],
                    "role": "CISA Coordinator",
                    "timestamp": "2026-11-05T20:45:27.204341Z",
                    "version": "2.0.3"
                  },
                  "type": "ssvc"
                }
              }
            ],
            "providerMetadata": {
              "dateUpdated": "2026-11-05T20:45:20.867Z",
              "orgId": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
              "shortName": "CISA-ADP"
            },
            "title": "CISA ADP Vulnrichment"
          }
        ],
        "cna": {
          "affected": [
            {
              "collectionURL": "https://repo.hex.pm",
              "cpes": [
                "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*"
              ],
              "defaultStatus": "unaffected",
              "modules": [
                "ezstd_nif",
                "ezstd"
              ],
              "packageName": "ezstd",
              "packageURL": "pkg:hex/ezstd",
              "product": "ezstd",
              "programFiles": [
                "c_src/ezstd_nif.cc",
                "src/ezstd_nif.erl",
                "src/ezstd.erl"
              ],
              "programRoutines": [
                {
                  "name": "zstd_nif_decompress_using_ddict"
                },
                {
                  "name": "ezstd_nif:decompress_using_ddict/2"
                },
                {
                  "name": "ezstd:decompress_using_ddict/2"
                }
              ],
              "repo": "https://github.com/silviucpp/ezstd",
              "vendor": "silviucpp",
              "versions": [
                {
                  "lessThan": "1.2.5",
                  "status": "affected",
                  "version": "1.0.5",
                  "versionType": "semver"
                }
              ]
            },
            {
              "collectionURL": "https://github.com",
              "cpes": [
                "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*"
              ],
              "defaultStatus": "unaffected",
              "modules": [
                "ezstd_nif",
                "ezstd"
              ],
              "packageName": "silviucpp/ezstd",
              "packageURL": "pkg:github/silviucpp/ezstd",
              "product": "ezstd",
              "programFiles": [
                "c_src/ezstd_nif.cc",
                "src/ezstd_nif.erl",
                "src/ezstd.erl"
              ],
              "programRoutines": [
                {
                  "name": "zstd_nif_decompress_using_ddict"
                },
                {
                  "name": "ezstd_nif:decompress_using_ddict/2"
                },
                {
                  "name": "ezstd:decompress_using_ddict/2"
                }
              ],
              "repo": "https://github.com/silviucpp/ezstd",
              "vendor": "silviucpp",
              "versions": [
                {
                  "lessThan": "e34f4a4f6dc18d990d1cece2d5fceef8e934a195",
                  "status": "affected",
                  "version": "6730128b1d35eca02a2028671421471ff651f423",
                  "versionType": "git"
                }
              ]
            }
          ],
          "cpeApplicability": [
            {
              "nodes": [
                {
                  "cpeMatch": [
                    {
                      "criteria": "cpe:2.3:a:silviucpp:ezstd:*:*:*:*:*:*:*:*",
                      "versionEndExcluding": "1.2.5",
                      "versionStartIncluding": "1.0.5",
                      "vulnerable": true
                    }
                  ],
                  "negate": false,
                  "operator": "OR"
                }
              ],
              "operator": "AND"
            }
          ],
          "credits": [
            {
              "lang": "en",
              "type": "finder",
              "value": "Oz Kaiser"
            },
            {
              "lang": "en",
              "type": "reporter",
              "value": "Oz Kaiser"
            },
            {
              "lang": "en",
              "type": "remediation developer",
              "value": "Silviu Caragea"
            },
            {
              "lang": "en",
              "type": "coordinator",
              "value": "Jonatan M\u00e4nnchen / EEF"
            }
          ],
          "dateAssigned": "2026-11-04T17:02:50.000Z",
          "descriptions": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003eImproper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003ezstd_nif_decompress_using_ddict\u003c/code\u003e in \u003ccode\u003ec_src/ezstd_nif.cc\u003c/code\u003e reads the frame\u0027s declared content size with \u003ccode\u003eZSTD_getFrameContentSize\u003c/code\u003e and passes it directly to \u003ccode\u003eenif_make_new_binary\u003c/code\u003e, without the 1 GiB \u003ccode\u003eMAX_BUFFER_SIZE\u003c/code\u003e check that \u003ccode\u003eezstd:decompress/1\u003c/code\u003e applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by \u003ccode\u003eezstd:decompress/1\u003c/code\u003e but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\u003c/p\u003e\n\u003cp\u003eThis issue affects ezstd: from 1.0.5 before 1.2.5.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to `ezstd:decompress_using_ddict/2` to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\n\n`zstd_nif_decompress_using_ddict` in `c_src/ezstd_nif.cc` reads the frame\u0027s declared content size with `ZSTD_getFrameContentSize` and passes it directly to `enif_make_new_binary`, without the 1 GiB `MAX_BUFFER_SIZE` check that `ezstd:decompress/1` applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by `ezstd:decompress/1` but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\n\nThis issue affects ezstd: from 1.0.5 before 1.2.5."
                }
              ],
              "value": "Improper Handling of Highly Compressed Data (Data Amplification) vulnerability in silviucpp ezstd allows an attacker who supplies a zstd frame to ezstd:decompress_using_ddict/2 to exhaust memory and terminate the Erlang VM via a small frame that declares a very large content size.\n\nzstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads the frame\u0027s declared content size with ZSTD_getFrameContentSize and passes it directly to enif_make_new_binary, without the 1 GiB MAX_BUFFER_SIZE check that ezstd:decompress/1 applies before allocating. A valid 65,550-byte frame of RLE blocks declaring 2 GiB is rejected by ezstd:decompress/1 but is fully allocated and decompressed by the dictionary path. The allocation happens inside a NIF, so when it exceeds the memory available to the VM the operating system kills the whole node rather than the calling process.\n\nThis issue affects ezstd: from 1.0.5 before 1.2.5."
            }
          ],
          "impacts": [
            {
              "capecId": "CAPEC-130",
              "descriptions": [
                {
                  "lang": "en",
                  "supportingMedia": [
                    {
                      "base64": false,
                      "type": "text/html",
                      "value": "\u003cp\u003eAn attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor.\u003c/p\u003e"
                    },
                    {
                      "base64": false,
                      "type": "text/markdown",
                      "value": "An attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor."
                    }
                  ],
                  "value": "An attacker who can submit a zstd frame to a service that decompresses it with a fixed dictionary can crash the entire Erlang VM with a single request of about 65 KiB. Every application and process hosted in that VM is taken down, not only the one that called the decompressor."
                }
              ]
            }
          ],
          "metrics": [
            {
              "cvssV4_0": {
                "Automatable": "NOT_DEFINED",
                "Recovery": "NOT_DEFINED",
                "Safety": "NOT_DEFINED",
                "attackComplexity": "LOW",
                "attackRequirements": "NONE",
                "attackVector": "LOCAL",
                "baseScore": 6.9,
                "baseSeverity": "MEDIUM",
                "privilegesRequired": "NONE",
                "providerUrgency": "NOT_DEFINED",
                "subAvailabilityImpact": "NONE",
                "subConfidentialityImpact": "NONE",
                "subIntegrityImpact": "NONE",
                "userInteraction": "NONE",
                "valueDensity": "NOT_DEFINED",
                "vectorString": "CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
                "version": "4.0",
                "vulnAvailabilityImpact": "HIGH",
                "vulnConfidentialityImpact": "NONE",
                "vulnIntegrityImpact": "NONE",
                "vulnerabilityResponseEffort": "NOT_DEFINED"
              },
              "format": "CVSS",
              "scenarios": [
                {
                  "lang": "en",
                  "value": "GENERAL"
                }
              ]
            }
          ],
          "problemTypes": [
            {
              "descriptions": [
                {
                  "cweId": "CWE-409",
                  "description": "CWE-409 Improper Handling of Highly Compressed Data (Data Amplification)",
                  "lang": "en",
                  "type": "CWE"
                }
              ]
            }
          ],
          "providerMetadata": {
            "dateUpdated": "2026-11-05T20:15:56.311Z",
            "orgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
            "shortName": "EEF"
          },
          "references": [
            {
              "name": "ezstd v1.2.5 release notes",
              "tags": [
                "release-notes",
                "related"
              ],
              "url": "https://github.com/silviucpp/ezstd/releases/tag/v1.2.5"
            },
            {
              "name": "EEF CNA record for CVE-2026-119434",
              "tags": [
                "related",
                "third-party-advisory"
              ],
              "url": "https://cna.erlef.org/cves/CVE-2026-119434.html"
            },
            {
              "name": "OSV record EEF-CVE-2026-119434",
              "tags": [
                "related"
              ],
              "url": "https://osv.dev/vulnerability/EEF-CVE-2026-119434"
            },
            {
              "name": "Introducing commit 6730128 in silviucpp/ezstd",
              "tags": [
                "related"
              ],
              "url": "https://github.com/silviucpp/ezstd/commit/6730128b1d35eca02a2028671421471ff651f423"
            },
            {
              "name": "Fix commit e34f4a4 in silviucpp/ezstd",
              "tags": [
                "patch"
              ],
              "url": "https://github.com/silviucpp/ezstd/commit/e34f4a4f6dc18d990d1cece2d5fceef8e934a195"
            }
          ],
          "source": {
            "discovery": "EXTERNAL"
          },
          "title": "Decompression bomb in ezstd:decompress_using_ddict/2 allows BEAM memory exhaustion via unbounded output buffer",
          "workarounds": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003eReplace calls to \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e with the streaming API: create a context with \u003ccode\u003eezstd:create_decompression_context/1\u003c/code\u003e using a small output buffer, attach the dictionary with \u003ccode\u003eezstd:select_ddict/2\u003c/code\u003e, and decompress with \u003ccode\u003eezstd:decompress_streaming/2\u003c/code\u003e. The streaming path decompresses into the caller-sized buffer and gives up with \u003ccode\u003e{error, decompressor_stuck}\u003c/code\u003e after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "Replace calls to `ezstd:decompress_using_ddict/2` with the streaming API: create a context with `ezstd:create_decompression_context/1` using a small output buffer, attach the dictionary with `ezstd:select_ddict/2`, and decompress with `ezstd:decompress_streaming/2`. The streaming path decompresses into the caller-sized buffer and gives up with `{error, decompressor_stuck}` after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload."
                }
              ],
              "value": "Replace calls to ezstd:decompress_using_ddict/2 with the streaming API: create a context with ezstd:create_decompression_context/1 using a small output buffer, attach the dictionary with ezstd:select_ddict/2, and decompress with ezstd:decompress_streaming/2. The streaming path decompresses into the caller-sized buffer and gives up with {error, decompressor_stuck} after 1000 chunks, so a 64 KiB buffer caps a single call at 64 MiB of output. Treat that error as a rejected input. Legitimate frames whose output exceeds 1000 times the buffer size fail the same way, so size the buffer for the largest expected payload."
            }
          ],
          "x_proofOfConcept": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003col\u003e\n\u003cli\u003eBuild ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\u003c/li\u003e\n\u003cli\u003eCreate any decompression dictionary with \u003ccode\u003eezstd:create_ddict/1\u003c/code\u003e; its content does not matter because the frame carries no dictionary ID.\u003c/li\u003e\n\u003cli\u003eConstruct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header \u003ccode\u003e0x02 0x00 0x10\u003c/code\u003e followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\u003c/li\u003e\n\u003cli\u003eCall \u003ccode\u003eezstd:decompress/1\u003c/code\u003e on the frame: it returns \u003ccode\u003e{error, \u0026lt;\u0026lt;\"frame too large or invalid\"\u0026gt;\u0026gt;}\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eCall \u003ccode\u003eezstd:decompress_using_ddict/2\u003c/code\u003e on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\u003c/li\u003e\n\u003cli\u003eRepeat on 1.2.5: the call returns \u003ccode\u003e{error, \u0026lt;\u0026lt;\"frame too large or invalid\"\u0026gt;\u0026gt;}\u003c/code\u003e and the VM continues.\u003c/li\u003e\n\u003c/ol\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "1. Build ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\n2. Create any decompression dictionary with `ezstd:create_ddict/1`; its content does not matter because the frame carries no dictionary ID.\n3. Construct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header `0x02 0x00 0x10` followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\n4. Call `ezstd:decompress/1` on the frame: it returns `{error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}`.\n5. Call `ezstd:decompress_using_ddict/2` on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\n6. Repeat on 1.2.5: the call returns `{error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}` and the VM continues."
                }
              ],
              "value": "* Build ezstd 1.2.4 and start a VM under an external memory limit, for example a container limited to 256 MiB.\n* Create any decompression dictionary with ezstd:create_ddict/1; its content does not matter because the frame carries no dictionary ID.\n* Construct a zstd frame: the magic number, a frame header descriptor selecting an 8-byte content size, a window descriptor, a little-endian content size of 2 GiB, then 16,383 RLE blocks of 128 KiB each (block header 0x02 0x00 0x10 followed by one payload byte) and a final RLE block with the last-block bit set. The frame is 65,550 bytes.\n* Call ezstd:decompress/1 on the frame: it returns {error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e}.\n* Call ezstd:decompress_using_ddict/2 on the same frame with the dictionary: the VM is killed by the operating system (exit status 137).\n* Repeat on 1.2.5: the call returns {error, \u003c\u003c\"frame too large or invalid\"\u003e\u003e} and the VM continues."
            }
          ],
          "x_technicalAnalysis": [
            {
              "lang": "en",
              "supportingMedia": [
                {
                  "base64": false,
                  "type": "text/html",
                  "value": "\u003cp\u003e\u003cstrong\u003e1. Declared size is attacker controlled.\u003c/strong\u003e A zstd frame header carries an optional Frame Content Size field. \u003ccode\u003ezstd_nif_decompress_using_ddict\u003c/code\u003e in \u003ccode\u003ec_src/ezstd_nif.cc\u003c/code\u003e reads it with \u003ccode\u003eZSTD_getFrameContentSize\u003c/code\u003e and rejects only the two sentinel values \u003ccode\u003eZSTD_CONTENTSIZE_UNKNOWN\u003c/code\u003e and \u003ccode\u003eZSTD_CONTENTSIZE_ERROR\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e2. Unbounded allocation.\u003c/strong\u003e The size is passed directly to \u003ccode\u003eenif_make_new_binary\u003c/code\u003e, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling \u003ccode\u003ezstd_nif_decompress\u003c/code\u003e rejects any declared size above \u003ccode\u003eMAX_BUFFER_SIZE\u003c/code\u003e (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e3. Amplification.\u003c/strong\u003e A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. \u003ccode\u003eZSTD_decompress_usingDDict\u003c/code\u003e then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception.\u003c/p\u003e"
                },
                {
                  "base64": false,
                  "type": "text/markdown",
                  "value": "**1. Declared size is attacker controlled.** A zstd frame header carries an optional Frame Content Size field. `zstd_nif_decompress_using_ddict` in `c_src/ezstd_nif.cc` reads it with `ZSTD_getFrameContentSize` and rejects only the two sentinel values `ZSTD_CONTENTSIZE_UNKNOWN` and `ZSTD_CONTENTSIZE_ERROR`.\n\n**2. Unbounded allocation.** The size is passed directly to `enif_make_new_binary`, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling `zstd_nif_decompress` rejects any declared size above `MAX_BUFFER_SIZE` (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\n\n**3. Amplification.** A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. `ZSTD_decompress_usingDDict` then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception."
                }
              ],
              "value": "1. Declared size is attacker controlled. A zstd frame header carries an optional Frame Content Size field. zstd_nif_decompress_using_ddict in c_src/ezstd_nif.cc reads it with ZSTD_getFrameContentSize and rejects only the two sentinel values ZSTD_CONTENTSIZE_UNKNOWN and ZSTD_CONTENTSIZE_ERROR.\n\n2. Unbounded allocation. The size is passed directly to enif_make_new_binary, so a frame declaring 2 GiB makes the NIF request a 2 GiB binary. The sibling zstd_nif_decompress rejects any declared size above MAX_BUFFER_SIZE (1 GiB) before allocating; the dictionary path omitted that check from the commit that introduced it.\n\n3. Amplification. A frame built from RLE blocks, each encoding 128 KiB of a repeated byte in four bytes, declares and genuinely decompresses to 2 GiB from 65,550 bytes of input, a ratio of about 32,760:1. ZSTD_decompress_usingDDict then fills the buffer. Because this happens inside a NIF, exceeding the memory available to the VM results in the operating system killing the whole BEAM process rather than an Erlang-level exception."
            }
          ]
        }
      },
      "cveMetadata": {
        "assignerOrgId": "6b3ad84c-e1a6-4bf7-a703-f496b71e49db",
        "assignerShortName": "EEF",
        "cveId": "CVE-2026-119434",
        "datePublished": "2026-11-05T20:15:56.311Z",
        "dateReserved": "2026-10-30T10:30:01.015Z",
        "dateUpdated": "2026-11-05T20:45:33.490Z",
        "state": "PUBLISHED"
      },
      "dataType": "CVE_RECORD",
      "dataVersion": "5.2"
    }
  }
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline

Sightings and recorded dates, grouped by day · UTC

JSON
How durations are calculated

Following the VTEM framework (Black Hat USA 2015), time to patch starts when the vendor or a coordinator was informed, total time to patch at discovery, and disclosure to patch at public disclosure; vendor response time runs from the report to its acknowledgement. Time to exploit and time unpatched start at the earliest discovery or report, falling back to public disclosure. Unpatched time ends at the first recorded patch, or the calculation time when no patch is recorded. Exploitation to patch shows the interval between those two events; a published proof of concept is a public exploit, not exploitation.

Each result shows its source dates. A negative interval means the end event came first; when date-only inputs leave the order open, the result says so. Date-only inputs are approximate. The earliest evidence wins: KEV report dates and sightings are labelled as such. Records describing another vulnerability are listed but never calculated from, and a PoC alone does not establish exploitation. Missing patch evidence does not prove that no patch exists. Filters below change the event list only.

Events included in the timeline

Loading timeline…


    Loading…

    Loading…

    Loading…

    Related by attack behaviour

    Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.