Common Weakness Enumeration

CWE-770

Allowed

Allocation of Resources Without Limits or Throttling

Abstraction: Base · Status: Incomplete

The product allocates a reusable resource or group of resources on behalf of an actor without imposing any intended restrictions on the size or number of resources that can be allocated.

4117 vulnerabilities reference this CWE, most recent first.

GHSA-VVR8-MHCC-GX9G

Vulnerability from github – Published: 2026-09-01 21:31 – Updated: 2026-09-01 21:31
VLAI
Details

Allocation of Resources Without Limits or Throttling (CWE-770) in Elasticsearch can lead to a denial of service via Excessive Allocation (CAPEC-130). A user with elevated privileges can submit a specially crafted request that causes excessive memory consumption, which may render the affected node unavailable.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-56143"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-770"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-09-01T20:17:14Z",
    "severity": "MODERATE"
  },
  "details": "Allocation of Resources Without Limits or Throttling (CWE-770) in Elasticsearch can lead to a denial of service via Excessive Allocation (CAPEC-130). A user with elevated privileges can submit a specially crafted request that causes excessive memory consumption, which may render the affected node unavailable.",
  "id": "GHSA-vvr8-mhcc-gx9g",
  "modified": "2026-09-01T21:31:47Z",
  "published": "2026-09-01T21:31:47Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-56143"
    },
    {
      "type": "WEB",
      "url": "https://discuss.elastic.co/t/elasticsearch-8-19-20-9-3-0-security-update-esa-2026-47/390084"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-VW22-2CVX-M8F8

Vulnerability from github – Published: 2022-05-24 19:19 – Updated: 2022-05-24 19:19
VLAI
Details

A memory allocation with excessive size value vulnerability in the license verification function of FortiPortal before 6.0.6 may allow an attacker to perform a denial of service attack via specially crafted license blobs.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-36174"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-770"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-11-02T19:15:00Z",
    "severity": "HIGH"
  },
  "details": "A memory allocation with excessive size value vulnerability in the license verification function of FortiPortal before 6.0.6 may allow an attacker to perform a denial of service attack via specially crafted license blobs.",
  "id": "GHSA-vw22-2cvx-m8f8",
  "modified": "2022-05-24T19:19:24Z",
  "published": "2022-05-24T19:19:24Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-36174"
    },
    {
      "type": "WEB",
      "url": "https://fortiguard.com/advisory/FG-IR-21-109"
    }
  ],
  "schema_version": "1.4.0",
  "severity": []
}

GHSA-VW3H-Q6XQ-JJM5

Vulnerability from github – Published: 2026-04-17 21:48 – Updated: 2026-06-08 23:25
VLAI
Summary
OpenClaw: Voice-call realtime WebSocket accepted oversized frames
Details

Summary

Voice-call realtime WebSocket accepted oversized frames.

Affected Packages / Versions

  • Package: openclaw
  • Ecosystem: npm
  • Affected versions: >= 2026.4.9 < 2026.4.10
  • Patched versions: >= 2026.4.10

Impact

The voice-call realtime WebSocket path could accept oversized frames, creating a remote availability risk for deployments exposing that webhook path.

Technical Details

The fix rejects oversized realtime WebSocket frames before processing them.

Fix

The issue was fixed in #63890. The first stable tag containing the fix is v2026.4.10, and openclaw@2026.4.14 includes the fix.

Fix Commit(s)

  • afadb7dae6738819ad9c7d2597ace0516957d20e
  • PR: #63890

Release Process Note

Users should upgrade to openclaw 2026.4.10 or newer. The latest npm release, 2026.4.14, already includes the fix.

Reporters

Thanks to G0odUser from ADLab of VenusTech Thanks to @zsxsoft, with sponsorship from @KeenSecurityLab and @qclawer for reporting this issue.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "openclaw"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2026.4.9"
            },
            {
              "fixed": "2026.4.10"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-42437"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400",
      "CWE-770"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-04-17T21:48:36Z",
    "nvd_published_at": "2026-05-05T12:16:18Z",
    "severity": "HIGH"
  },
  "details": "## Summary\n\nVoice-call realtime WebSocket accepted oversized frames.\n\n## Affected Packages / Versions\n\n- Package: `openclaw`\n- Ecosystem: npm\n- Affected versions: `\u003e= 2026.4.9 \u003c 2026.4.10`\n- Patched versions: `\u003e= 2026.4.10`\n\n## Impact\n\nThe voice-call realtime WebSocket path could accept oversized frames, creating a remote availability risk for deployments exposing that webhook path.\n\n## Technical Details\n\nThe fix rejects oversized realtime WebSocket frames before processing them.\n\n## Fix\n\nThe issue was fixed in #63890. The first stable tag containing the fix is `v2026.4.10`, and `openclaw@2026.4.14` includes the fix.\n\n## Fix Commit(s)\n\n- `afadb7dae6738819ad9c7d2597ace0516957d20e`\n- PR: #63890\n\n## Release Process Note\n\nUsers should upgrade to `openclaw` 2026.4.10 or newer. The latest npm release, `2026.4.14`, already includes the fix.\n\n## Reporters\n\nThanks to G0odUser from ADLab of VenusTech\nThanks to @zsxsoft, with sponsorship from @KeenSecurityLab and @qclawer for reporting this issue.",
  "id": "GHSA-vw3h-q6xq-jjm5",
  "modified": "2026-06-08T23:25:32Z",
  "published": "2026-04-17T21:48:36Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/security/advisories/GHSA-vw3h-q6xq-jjm5"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-42437"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/pull/63890"
    },
    {
      "type": "WEB",
      "url": "https://github.com/openclaw/openclaw/commit/afadb7dae6738819ad9c7d2597ace0516957d20e"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/openclaw/openclaw"
    },
    {
      "type": "WEB",
      "url": "https://www.vulncheck.com/advisories/openclaw-denial-of-service-via-oversized-websocket-frames-in-voice-call-realtime-path"
    }
  ],
  "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:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "OpenClaw: Voice-call realtime WebSocket accepted oversized frames"
}

GHSA-VWC8-VMVR-QQCF

Vulnerability from github – Published: 2024-03-27 09:30 – Updated: 2024-08-05 18:31
VLAI
Details

An issue was discovered in Couchbase Server 6.6.x through 7.2.0, before 7.1.5 and 7.2.1. Unauthenticated users may cause memcached to run out of memory via large commands.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2023-43768"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-770"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2024-03-27T07:15:48Z",
    "severity": "HIGH"
  },
  "details": "An issue was discovered in Couchbase Server 6.6.x through 7.2.0, before 7.1.5 and 7.2.1. Unauthenticated users may cause memcached to run out of memory via large commands.",
  "id": "GHSA-vwc8-vmvr-qqcf",
  "modified": "2024-08-05T18:31:42Z",
  "published": "2024-03-27T09:30:39Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-43768"
    },
    {
      "type": "WEB",
      "url": "https://docs.couchbase.com/server/current/release-notes/relnotes.html"
    },
    {
      "type": "WEB",
      "url": "https://forums.couchbase.com/tags/security"
    },
    {
      "type": "WEB",
      "url": "https://www.couchbase.com/alerts"
    },
    {
      "type": "WEB",
      "url": "https://www.couchbase.com/downloads"
    }
  ],
  "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-VWCX-7W56-22RQ

Vulnerability from github – Published: 2022-05-24 17:39 – Updated: 2022-08-06 00:00
VLAI
Details

A vulnerability in processing of certain DHCP packets from adjacent clients on EX Series and QFX Series switches running Juniper Networks Junos OS with DHCP local/relay server configured may lead to exhaustion of DMA memory causing a Denial of Service (DoS). Over time, exploitation of this vulnerability may cause traffic to stop being forwarded, or to crashing of the fxpc process. When Packet DMA heap utilization reaches 99%, the system will become unstable. Packet DMA heap utilization can be monitored through the following command: user@junos# request pfe execute target fpc0 timeout 30 command "show heap" ID Base Total(b) Free(b) Used(b) % Name -- ---------- ----------- ----------- ----------- --- ----------- 0 213301a8 536870488 387228840 149641648 27 Kernel 1 91800000 8388608 3735120 4653488 55 DMA 2 92000000 75497472 74452192 1045280 1 PKT DMA DESC 3 d330000 335544320 257091400 78452920 23 Bcm_sdk 4 96800000 184549376 2408 184546968 99 Packet DMA <--- 5 903fffe0 20971504 20971504 0 0 Blob An indication of the issue occurring may be observed through the following log messages: Dec 10 08:07:00.124 2020 hostname fpc0 brcm_pkt_buf_alloc:523 (buf alloc) failed allocating packet buffer Dec 10 08:07:00.126 2020 hostname fpc0 (buf alloc) failed allocating packet buffer Dec 10 08:07:00.128 2020 hostname fpc0 brcm_pkt_buf_alloc:523 (buf alloc) failed allocating packet buffer Dec 10 08:07:00.130 2020 hostnameC fpc0 (buf alloc) failed allocating packet buffer This issue affects Juniper Networks Junos OS on EX Series and QFX Series: 17.4R3 versions prior to 17.4R3-S3; 18.1R3 versions between 18.1R3-S6 and 18.1R3-S11; 18.2R3 versions prior to 18.2R3-S6; 18.3R3 versions prior to 18.3R3-S4; 18.4R2 versions prior to 18.4R2-S5; 18.4R3 versions prior to 18.4R3-S6; 19.1 versions between 19.1R2 and 19.1R3-S3; 19.2 versions prior to 19.2R3-S1; 19.3 versions prior to 19.3R2-S5, 19.3R3; 19.4 versions prior to 19.4R2-S2, 19.4R3; 20.1 versions prior to 20.1R2; 20.2 versions prior to 20.2R1-S2, 20.2R2. Junos OS versions prior to 17.4R3 are unaffected by this vulnerability.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-0217"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-119",
      "CWE-770"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-01-15T18:15:00Z",
    "severity": "HIGH"
  },
  "details": "A vulnerability in processing of certain DHCP packets from adjacent clients on EX Series and QFX Series switches running Juniper Networks Junos OS with DHCP local/relay server configured may lead to exhaustion of DMA memory causing a Denial of Service (DoS). Over time, exploitation of this vulnerability may cause traffic to stop being forwarded, or to crashing of the fxpc process. When Packet DMA heap utilization reaches 99%, the system will become unstable. Packet DMA heap utilization can be monitored through the following command: user@junos# request pfe execute target fpc0 timeout 30 command \"show heap\" ID Base Total(b) Free(b) Used(b) % Name -- ---------- ----------- ----------- ----------- --- ----------- 0 213301a8 536870488 387228840 149641648 27 Kernel 1 91800000 8388608 3735120 4653488 55 DMA 2 92000000 75497472 74452192 1045280 1 PKT DMA DESC 3 d330000 335544320 257091400 78452920 23 Bcm_sdk 4 96800000 184549376 2408 184546968 99 Packet DMA \u003c--- 5 903fffe0 20971504 20971504 0 0 Blob An indication of the issue occurring may be observed through the following log messages: Dec 10 08:07:00.124 2020 hostname fpc0 brcm_pkt_buf_alloc:523 (buf alloc) failed allocating packet buffer Dec 10 08:07:00.126 2020 hostname fpc0 (buf alloc) failed allocating packet buffer Dec 10 08:07:00.128 2020 hostname fpc0 brcm_pkt_buf_alloc:523 (buf alloc) failed allocating packet buffer Dec 10 08:07:00.130 2020 hostnameC fpc0 (buf alloc) failed allocating packet buffer This issue affects Juniper Networks Junos OS on EX Series and QFX Series: 17.4R3 versions prior to 17.4R3-S3; 18.1R3 versions between 18.1R3-S6 and 18.1R3-S11; 18.2R3 versions prior to 18.2R3-S6; 18.3R3 versions prior to 18.3R3-S4; 18.4R2 versions prior to 18.4R2-S5; 18.4R3 versions prior to 18.4R3-S6; 19.1 versions between 19.1R2 and 19.1R3-S3; 19.2 versions prior to 19.2R3-S1; 19.3 versions prior to 19.3R2-S5, 19.3R3; 19.4 versions prior to 19.4R2-S2, 19.4R3; 20.1 versions prior to 20.1R2; 20.2 versions prior to 20.2R1-S2, 20.2R2. Junos OS versions prior to 17.4R3 are unaffected by this vulnerability.",
  "id": "GHSA-vwcx-7w56-22rq",
  "modified": "2022-08-06T00:00:38Z",
  "published": "2022-05-24T17:39:20Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-0217"
    },
    {
      "type": "WEB",
      "url": "https://kb.juniper.net/JSA11107"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:C/C:N/I:N/A:H",
      "type": "CVSS_V3"
    }
  ]
}

GHSA-VWQH-MHGJ-P4M8

Vulnerability from github – Published: 2022-05-24 19:16 – Updated: 2023-07-07 21:30
VLAI
Details

Multiple vulnerabilities in the Cisco ATA 190 Series Analog Telephone Adapter Software could allow an attacker to perform a command injection attack resulting in remote code execution or cause a denial of service (DoS) condition on an affected device. For more information about these vulnerabilities, see the Details section of this advisory.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2021-34735"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-77",
      "CWE-770"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2021-10-06T20:15:00Z",
    "severity": "HIGH"
  },
  "details": "Multiple vulnerabilities in the Cisco ATA 190 Series Analog Telephone Adapter Software could allow an attacker to perform a command injection attack resulting in remote code execution or cause a denial of service (DoS) condition on an affected device. For more information about these vulnerabilities, see the Details section of this advisory.",
  "id": "GHSA-vwqh-mhgj-p4m8",
  "modified": "2023-07-07T21:30:15Z",
  "published": "2022-05-24T19:16:40Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-34735"
    },
    {
      "type": "WEB",
      "url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-ata19x-multivuln-A4J57F3"
    }
  ],
  "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-VX3V-MCRW-7985

Vulnerability from github – Published: 2026-08-05 09:31 – Updated: 2026-08-07 00:31
VLAI
Details

An authenticated attacker could exceed the session flow control incoming window potentially leading to denial of service.

This issue affects Apache Qpid Proton-J: through 0.34.1.

Users are recommended to upgrade to version 0.35.0, which fixes the issue.

Show details on source website

{
  "affected": [],
  "aliases": [
    "CVE-2026-66275"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-770"
    ],
    "github_reviewed": false,
    "github_reviewed_at": null,
    "nvd_published_at": "2026-08-05T07:16:37Z",
    "severity": "MODERATE"
  },
  "details": "An authenticated attacker could exceed the session flow control incoming window potentially leading to denial of service.\n\nThis issue affects Apache Qpid Proton-J: through 0.34.1.\n\nUsers are recommended to upgrade to version 0.35.0, which fixes the issue.",
  "id": "GHSA-vx3v-mcrw-7985",
  "modified": "2026-08-07T00:31:08Z",
  "published": "2026-08-05T09:31:15Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-66275"
    },
    {
      "type": "WEB",
      "url": "https://lists.apache.org/thread/jds59nxrgcxtlx7xl0kvl5hqt07thxzt"
    },
    {
      "type": "WEB",
      "url": "http://www.openwall.com/lists/oss-security/2026/08/04/11"
    }
  ],
  "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"
    }
  ]
}

GHSA-VX6W-VV9F-6GVG

Vulnerability from github – Published: 2026-10-20 20:53 – Updated: 2026-10-20 20:53
VLAI
Summary
Pillow: EPS load(scale) lets Ghostscript render past the decompression bomb limit
Details
============================================================================
EPS load(scale) lets Ghostscript render past the decompression bomb limit
Location: src/PIL/EpsImagePlugin.py:92  in Ghostscript()
Commit:   a707c6b21c313880d0771e54965d142dd42358b6
============================================================================

When an application opens an untrusted Encapsulated PostScript file and asks Pillow to render it at a larger scale, Pillow has Ghostscript produce an image several times bigger than Pillow's configured size limit allows. The size check runs only after Ghostscript has finished rendering and written the full raw image to a temporary file. An attacker who can upload a file of about 100 bytes makes each such request spend scale² times the Ghostscript rendering work and temporary disk space that the limit is meant to permit. For example, at scale 2 that is a 972 MB temporary file.

The cause is in Ghostscript() in src/PIL/EpsImagePlugin.py. It multiplies the file-declared size by the caller's scale (lines 93-94) and passes the product to gs as the -g output geometry. It never calls Image._decompression_bomb_check() on the scaled size. The only check is the one Image.open() ran on the unscaled size, so a file declaring 9000×9000 passes, and load(scale=2) then asks Ghostscript for 18000×18000 (3.6× MAX_IMAGE_PIXELS). A file declaring 18000×18000 directly would be refused before Ghostscript ever ran. DecompressionBombError fires only when Pillow reopens the output file, so Pillow's own in-process allocation stays bounded and there is no memory corruption.

The effect is a constant-factor overshoot rather than an unbounded one, for three reasons:

  • The multiplier is an integer chosen by the application, not by the file.
  • With the default warning filter, Image.open() already lets files up to 2× the limit reach Ghostscript at scale=1.
  • Any application feeding untrusted files to Ghostscript is already exposed to a tiny file that keeps Ghostscript busy indefinitely, since gs runs with no timeout.

This is the EPS counterpart of the WMF load(dpi) gap closed in af70b075a. It has been present since the decompression-bomb limit was introduced in ce2955ec7 (2.5.0). The attached reproducer stubs out Ghostscript and shows a 76-byte file passing Image.open() and reaching gs with -g18000x18000. A one-line patch mirroring the WMF check is included.

Details

EpsImageFile.load(scale=N) (the documented way to rasterise an EPS at higher resolution) renders width*N × height*N pixels through Ghostscript, but the only decompression-bomb check on the way is the one Image.open() ran on the unscaled, file-declared width × height. The scaled product is never passed to Image._decompression_bomb_check() before gs is started.

This 111-byte EPS declares 9000×9000 = 81,000,000 pixels, below the default MAX_IMAGE_PIXELS (89,478,485), so Image.open() accepts it without even a warning:

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 9000 9000
%%EndComments
0 0 moveto 9000 9000 lineto stroke
showpage

im.load(scale=2) on it then executes

gs -q -g18000x18000 -r144.000000x144.000000 -dBATCH -dNOPAUSE -dSAFER -sDEVICE=pnmraw -sOutputFile=/tmp/tmpXXXX -c 0 0 translate -f attack.eps -c showpage

i.e. asks Ghostscript for an 18000×18000 = 324,000,000-pixel raster (3.6× MAX_IMAGE_PIXELS), whose pnmraw output is a 972,000,019-byte file in the temp directory. An EPS that declares 18000×18000 directly is rejected by Image.open() with DecompressionBombError before Ghostscript is ever run; via scale=2 the same raster is rendered first and the DecompressionBombError only appears afterwards, when Pillow opens the file Ghostscript produced. (Between 1× and 2× MAX_IMAGE_PIXELS, Image.open() only emits DecompressionBombWarning, so with the default warning filter an EPS declaring e.g. 13377×13377 is already rendered at scale=1 — a 537 MB PNM. Against that baseline, scale=2 is 4× an already-permitted render.)

The arithmetic is in Ghostscript():

# src/PIL/EpsImagePlugin.py:91-97
    # Hack to support hi-res rendering
    scale = int(scale) or 1
    width = size[0] * scale
    height = size[1] * scale
    # resolution is dependent on bbox and size
    res_x = 72.0 * width / (bbox[2] - bbox[0])
    …
# src/PIL/EpsImagePlugin.py:139-142
    command = [
        gs_binary,
        "-q",  # quiet mode
        f"-g{width:d}x{height:d}",  # set output geometry (pixels)
    …
# src/PIL/EpsImagePlugin.py:165-168
        subprocess.check_call(command, startupinfo=startupinfo)
        with Image.open(outfile) as out_im:
            out_im.load()
            return out_im.im.copy()

and its caller does nothing between taking scale from the application and invoking it:

# src/PIL/EpsImagePlugin.py:411-417
    def load(self, scale: int = 1, transparency: bool = False) -> …:
        # Load EPS via Ghostscript
        if self.tile:
            assert self.fp is not None
            self.im = Ghostscript(self.tile, self.size, self.fp, scale, transparency)

size here is self._size, computed in _open() from the file's %%BoundingBox (or %ImageData) and checked once by Image.open() at src/PIL/Image.py:3700. For the benign path (scale=1) that check covers exactly what Ghostscript is asked to render. For scale=N the rendered pixel count is N² times what was checked, so a file can sit just under the limit at open time and have Ghostscript render 4× (scale 2), 9× (scale 3), 16× (scale 4) the configured budget. The first point at which Pillow looks at the real size again is Image.open(outfile) at line 166 — after subprocess.check_call has returned, i.e. after Ghostscript has spent the CPU and written width*height*3 bytes to tempfile.mkstemp()'s directory.

WmfStubImageFile.load(dpi) has the same shape (file-derived extent × caller-supplied factor → new raster) and, since af70b075a, calls Image._decompression_bomb_check(self.size) on the recomputed size before rendering (src/PIL/WmfImagePlugin.py:127-131). The EPS path lacks the equivalent line. The gap dates from ce2955ec7128 ("Throw an exception when an opened image is larger than an arbitrary limit", 2014-05-14, first released in 2.5.0), which added the check to Image.open() without covering the scale path.

Impact

Affected are applications that open untrusted EPS/PS with Ghostscript installed and call load(scale=N) with a fixed N > 1, as the handbook suggests for non-blurry output. Handing untrusted EPS to Ghostscript at all already lets the same attacker tie up a worker with an equally tiny file (e.g. a PostScript {} loop; Pillow runs gs with no timeout), so this bug adds a constant factor rather than a new denial-of-service capability. Within that setting, a ~110-byte upload makes each request run Ghostscript over N² × MAX_IMAGE_PIXELS pixels (N² × 2·MAX_IMAGE_PIXELS if the application does not turn DecompressionBombWarning into an error) and write a W·H·3-byte PNM into the temp directory — 972 MB for the example above at scale 2, 2.2 GB at scale 3, 8.6 GB for a 178-Mpixel declaration at scale 4 — before any limit is applied. The operator's MAX_IMAGE_PIXELS setting is exceeded by a factor of N²; N is an integer chosen by the application, not by the file, so the work stays bounded at N² × 2·MAX_IMAGE_PIXELS. The consequence is N² more Ghostscript CPU and temp-disk use per request than the configured limit intends; Pillow's own in-process pixel allocation remains bounded because Image.open(outfile) re-checks the PNM's size, and there is no memory corruption.

This is a sibling of the WMF load(dpi) issue fixed in af70b075a ("Add decompression bomb check when loading at a different DPI"); the EPS scale path was not covered by that change. Unlike the WMF case, where the file-controlled _inch makes the ratio unbounded, the EPS multiplier is fixed by the application.

Reproducing

Run repro against the installed Pillow. Ghostscript does not need to be installed: the script sets EpsImagePlugin.gs_binary = "gs" so that has_ghostscript() skips its gs --version probe, and replaces subprocess.check_call with a function that records the command line Pillow builds and then raises OSError, so nothing is actually rendered.

It writes a 76-byte EPS declaring %%BoundingBox: 0 0 9000 9000 (the example above without the drawing line; 81 Mpixel, below the default MAX_IMAGE_PIXELS of 89,478,485) and turns DecompressionBombWarning into an error, so any bomb check — warning or hard error — counts. It then calls Image.open() and im.load(scale=2). Image.open() accepts the file and load(scale=2) reaches the intercepted Ghostscript call with -g18000x18000 (324,000,000 pixels, 3.6× MAX_IMAGE_PIXELS, a 972 MB pnmraw output with real Ghostscript). The script prints the geometry it captured.

It prints BUG when Ghostscript was invoked with a -g geometry above 2*MAX_IMAGE_PIXELS (178,956,970) and no decompression-bomb check fired before that call; otherwise it prints OK. With the attached patch applied, load(scale=2) raises DecompressionBombError before Ghostscript is called and the script prints OK.

Suggested fix

The attached patch checks the scaled size in Ghostscript() right after the scaled width/height are computed (src/PIL/EpsImagePlugin.py:93-94) and before the gs command is built, mirroring WmfStubImageFile.load:

--- a/src/PIL/EpsImagePlugin.py
+++ b/src/PIL/EpsImagePlugin.py
@@ -92,6 +92,7 @@ def Ghostscript(
     scale = int(scale) or 1
     width = size[0] * scale
     height = size[1] * scale
+    Image._decompression_bomb_check((width, height))
     # resolution is dependent on bbox and size
     res_x = 72.0 * width / (bbox[2] - bbox[0])
     res_y = 72.0 * height / (bbox[3] - bbox[1])

load(scale=N) now raises DecompressionBombError / emits DecompressionBombWarning under the same MAX_IMAGE_PIXELS thresholds Image.open() applies, before Ghostscript runs instead of after. Placing the check in Ghostscript() rather than in EpsImageFile.load() is the single point where the rendered extent is decided, so it also covers direct callers of the module-level function. With the patch applied to a clean checkout the reproducer prints OK and Tests/test_file_eps.py passes. One cosmetic side effect: at scale=1 the check re-emits the DecompressionBombWarning that Image.open() already issued for sizes between 1× and 2× the limit; guarding the call with if scale > 1: would avoid the duplicate.

The patch also adds test_load_scale_decompression_bomb to Tests/test_file_eps.py, in the style of the WMF test: it sets MAX_IMAGE_PIXELS to im.width * im.height and expects im.load(scale=2) to raise DecompressionBombError. Like the rest of that file it is skipped without Ghostscript, because has_ghostscript() is consulted at the top of Ghostscript(); moving the check above that call would let the test run without it.

The patch

Add decompression bomb check on the scaled size in EpsImagePlugin.Ghostscript() before Ghostscript is invoked

Applies to src/PIL/EpsImagePlugin.py at the commit above.

diff --git a/Tests/test_file_eps.py b/Tests/test_file_eps.py
index 70eced62a..de331d97f 100644
--- a/Tests/test_file_eps.py
+++ b/Tests/test_file_eps.py
@@ -98,6 +98,14 @@ def test_sanity(filename: str, size: tuple[int, int], scale: int) -> None:
         assert image.format == "EPS"


+@pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
+def test_load_scale_decompression_bomb(monkeypatch: pytest.MonkeyPatch) -> None:
+    with Image.open(FILE1) as im:
+        monkeypatch.setattr(Image, "MAX_IMAGE_PIXELS", im.width * im.height)
+        with pytest.raises(Image.DecompressionBombError):
+            im.load(scale=2)
+
+
 @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason="Ghostscript not available")
 def test_load() -> None:
     with Image.open(FILE1) as im:
diff --git a/src/PIL/EpsImagePlugin.py b/src/PIL/EpsImagePlugin.py
index 5eaefe339..ccc6f1d85 100644
--- a/src/PIL/EpsImagePlugin.py
+++ b/src/PIL/EpsImagePlugin.py
@@ -92,6 +92,7 @@ def Ghostscript(
     scale = int(scale) or 1
     width = size[0] * scale
     height = size[1] * scale
+    Image._decompression_bomb_check((width, height))
     # resolution is dependent on bbox and size
     res_x = 72.0 * width / (bbox[2] - bbox[0])
     res_y = 72.0 * height / (bbox[3] - bbox[1])

The reproducer

Reproducer — repro, 1,845 bytes (click to open) Its last line is `BUG` when the issue triggers and `OK` when it does not. Re-run on a clean build of that commit it printed `BUG`.
#!/usr/bin/env python3
# EpsImagePlugin.Ghostscript(): load(scale=N) hands gs a -g geometry of
# (W*N)x(H*N) with no _decompression_bomb_check on the scaled size; only the
# unscaled WxH was checked by Image.open(). gs is not installed here, so we
# set gs_binary and intercept subprocess.check_call to read the argv Pillow builds.
import os, subprocess, tempfile, warnings
from PIL import Image, EpsImagePlugin

EpsImagePlugin.gs_binary = "gs"  # skip the `gs --version` probe
path = os.path.join(tempfile.mkdtemp(), "a.eps")
with open(path, "w") as f:  # 9000x9000 = 81 Mpx < MAX_IMAGE_PIXELS (89.5 Mpx)
    f.write("%!PS-Adobe-3.0 EPSF-3.0\n%%BoundingBox: 0 0 9000 9000\n%%EndComments\nshowpage\n")

calls = []
def fake_check_call(cmd, **kw):
    calls.append(cmd)
    raise OSError("gs intercepted")  # stop here; we only need the argv
subprocess.check_call = fake_check_call

hard = 2 * Image.MAX_IMAGE_PIXELS
bomb_before_gs = False
with warnings.catch_warnings():
    warnings.simplefilter("error", Image.DecompressionBombWarning)
    try:
        with Image.open(path) as im:
            print("Image.open accepted", os.path.getsize(path), "byte EPS, size", im.size)
            im.load(scale=2)
    except (Image.DecompressionBombError, Image.DecompressionBombWarning) as e:
        bomb_before_gs = not calls
        print("bomb check fired", "before" if bomb_before_gs else "after", "gs:", e)
    except OSError as e:
        print("load() reached gs:", e)

over = False
for c in calls:
    g = next(a for a in c if a.startswith("-g"))[2:]
    w, h = map(int, g.split("x"))
    over |= w * h > hard
    print(f"gs argv geometry -g{g} = {w*h} px ({w*h/Image.MAX_IMAGE_PIXELS:.1f}x MAX_IMAGE_PIXELS, "
          f"hard limit {hard}); pnmraw output would be {w*h*3} bytes")
print("BUG" if calls and over and not bomb_before_gs else "OK")

Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 12.3.0"
      },
      "package": {
        "ecosystem": "PyPI",
        "name": "Pillow"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2.3.0"
            },
            {
              "fixed": "13.0.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-112899"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-770"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-10-20T20:53:21Z",
    "nvd_published_at": null,
    "severity": "MODERATE"
  },
  "details": "```\n============================================================================\nEPS load(scale) lets Ghostscript render past the decompression bomb limit\nLocation: src/PIL/EpsImagePlugin.py:92  in Ghostscript()\nCommit:   a707c6b21c313880d0771e54965d142dd42358b6\n============================================================================\n```\n\nWhen an application opens an untrusted Encapsulated PostScript file and asks Pillow to render it at a larger scale, Pillow has Ghostscript produce an image several times bigger than Pillow\u0027s configured size limit allows. The size check runs only after Ghostscript has finished rendering and written the full raw image to a temporary file. An attacker who can upload a file of about 100 bytes makes each such request spend scale\u00b2 times the Ghostscript rendering work and temporary disk space that the limit is meant to permit. For example, at scale 2 that is a 972 MB temporary file.\n\nThe cause is in `Ghostscript()` in `src/PIL/EpsImagePlugin.py`. It multiplies the file-declared size by the caller\u0027s `scale` (lines 93-94) and passes the product to `gs` as the `-g` output geometry. It never calls `Image._decompression_bomb_check()` on the scaled size. The only check is the one `Image.open()` ran on the unscaled size, so a file declaring 9000\u00d79000 passes, and `load(scale=2)` then asks Ghostscript for 18000\u00d718000 (3.6\u00d7 `MAX_IMAGE_PIXELS`). A file declaring 18000\u00d718000 directly would be refused before Ghostscript ever ran. `DecompressionBombError` fires only when Pillow reopens the output file, so Pillow\u0027s own in-process allocation stays bounded and there is no memory corruption.\n\nThe effect is a constant-factor overshoot rather than an unbounded one, for three reasons:\n\n* The multiplier is an integer chosen by the application, not by the file.\n* With the default warning filter, `Image.open()` already lets files up to 2\u00d7 the limit reach Ghostscript at `scale=1`.\n* Any application feeding untrusted files to Ghostscript is already exposed to a tiny file that keeps Ghostscript busy indefinitely, since `gs` runs with no timeout.\n\nThis is the EPS counterpart of the WMF `load(dpi)` gap closed in af70b075a. It has been present since the decompression-bomb limit was introduced in ce2955ec7 (2.5.0). The attached reproducer stubs out Ghostscript and shows a 76-byte file passing `Image.open()` and reaching `gs` with `-g18000x18000`. A one-line patch mirroring the WMF check is included.\n\n## Details\n\n`EpsImageFile.load(scale=N)` (the documented way to rasterise an EPS at higher resolution) renders `width*N \u00d7 height*N` pixels through Ghostscript, but the only decompression-bomb check on the way is the one `Image.open()` ran on the *unscaled*, file-declared `width \u00d7 height`. The scaled product is never passed to `Image._decompression_bomb_check()` before `gs` is started.\n\nThis 111-byte EPS declares 9000\u00d79000 = 81,000,000 pixels, below the default `MAX_IMAGE_PIXELS` (89,478,485), so `Image.open()` accepts it without even a warning:\n\n```\n%!PS-Adobe-3.0 EPSF-3.0\n%%BoundingBox: 0 0 9000 9000\n%%EndComments\n0 0 moveto 9000 9000 lineto stroke\nshowpage\n```\n\n`im.load(scale=2)` on it then executes\n\n```\ngs -q -g18000x18000 -r144.000000x144.000000 -dBATCH -dNOPAUSE -dSAFER -sDEVICE=pnmraw -sOutputFile=/tmp/tmpXXXX -c 0 0 translate -f attack.eps -c showpage\n```\n\ni.e. asks Ghostscript for an 18000\u00d718000 = 324,000,000-pixel raster (3.6\u00d7 `MAX_IMAGE_PIXELS`), whose `pnmraw` output is a 972,000,019-byte file in the temp directory. An EPS that declares 18000\u00d718000 directly is rejected by `Image.open()` with `DecompressionBombError` before Ghostscript is ever run; via `scale=2` the same raster is rendered first and the `DecompressionBombError` only appears afterwards, when Pillow opens the file Ghostscript produced. (Between 1\u00d7 and 2\u00d7 `MAX_IMAGE_PIXELS`, `Image.open()` only emits `DecompressionBombWarning`, so with the default warning filter an EPS declaring e.g. 13377\u00d713377 is already rendered at `scale=1` \u2014 a 537 MB PNM. Against that baseline, `scale=2` is 4\u00d7 an already-permitted render.)\n\nThe arithmetic is in `Ghostscript()`:\n\n```python\n# src/PIL/EpsImagePlugin.py:91-97\n    # Hack to support hi-res rendering\n    scale = int(scale) or 1\n    width = size[0] * scale\n    height = size[1] * scale\n    # resolution is dependent on bbox and size\n    res_x = 72.0 * width / (bbox[2] - bbox[0])\n    \u2026\n# src/PIL/EpsImagePlugin.py:139-142\n    command = [\n        gs_binary,\n        \"-q\",  # quiet mode\n        f\"-g{width:d}x{height:d}\",  # set output geometry (pixels)\n    \u2026\n# src/PIL/EpsImagePlugin.py:165-168\n        subprocess.check_call(command, startupinfo=startupinfo)\n        with Image.open(outfile) as out_im:\n            out_im.load()\n            return out_im.im.copy()\n```\n\nand its caller does nothing between taking `scale` from the application and invoking it:\n\n```python\n# src/PIL/EpsImagePlugin.py:411-417\n    def load(self, scale: int = 1, transparency: bool = False) -\u003e \u2026:\n        # Load EPS via Ghostscript\n        if self.tile:\n            assert self.fp is not None\n            self.im = Ghostscript(self.tile, self.size, self.fp, scale, transparency)\n```\n\n`size` here is `self._size`, computed in `_open()` from the file\u0027s `%%BoundingBox` (or `%ImageData`) and checked once by `Image.open()` at `src/PIL/Image.py:3700`. For the benign path (`scale=1`) that check covers exactly what Ghostscript is asked to render. For `scale=N` the rendered pixel count is N\u00b2 times what was checked, so a file can sit just under the limit at open time and have Ghostscript render 4\u00d7 (scale 2), 9\u00d7 (scale 3), 16\u00d7 (scale 4) the configured budget. The first point at which Pillow looks at the real size again is `Image.open(outfile)` at line 166 \u2014 after `subprocess.check_call` has returned, i.e. after Ghostscript has spent the CPU and written `width*height*3` bytes to `tempfile.mkstemp()`\u0027s directory.\n\n`WmfStubImageFile.load(dpi)` has the same shape (file-derived extent \u00d7 caller-supplied factor \u2192 new raster) and, since af70b075a, calls `Image._decompression_bomb_check(self.size)` on the recomputed size before rendering (`src/PIL/WmfImagePlugin.py:127-131`). The EPS path lacks the equivalent line. The gap dates from ce2955ec7128 (\"Throw an exception when an opened image is larger than an arbitrary limit\", 2014-05-14, first released in 2.5.0), which added the check to `Image.open()` without covering the `scale` path.\n\n## Impact\n\nAffected are applications that open untrusted EPS/PS with Ghostscript installed and call `load(scale=N)` with a fixed N \u003e 1, as the handbook suggests for non-blurry output. Handing untrusted EPS to Ghostscript at all already lets the same attacker tie up a worker with an equally tiny file (e.g. a PostScript `{} loop`; Pillow runs `gs` with no timeout), so this bug adds a constant factor rather than a new denial-of-service capability. Within that setting, a ~110-byte upload makes each request run Ghostscript over N\u00b2 \u00d7 `MAX_IMAGE_PIXELS` pixels (N\u00b2 \u00d7 2\u00b7`MAX_IMAGE_PIXELS` if the application does not turn `DecompressionBombWarning` into an error) and write a `W\u00b7H\u00b73`-byte PNM into the temp directory \u2014 972 MB for the example above at scale 2, 2.2 GB at scale 3, 8.6 GB for a 178-Mpixel declaration at scale 4 \u2014 before any limit is applied. The operator\u0027s `MAX_IMAGE_PIXELS` setting is exceeded by a factor of N\u00b2; N is an integer chosen by the application, not by the file, so the work stays bounded at N\u00b2 \u00d7 2\u00b7`MAX_IMAGE_PIXELS`. The consequence is N\u00b2 more Ghostscript CPU and temp-disk use per request than the configured limit intends; Pillow\u0027s own in-process pixel allocation remains bounded because `Image.open(outfile)` re-checks the PNM\u0027s size, and there is no memory corruption.\n\nThis is a sibling of the WMF `load(dpi)` issue fixed in af70b075a (\"Add decompression bomb check when loading at a different DPI\"); the EPS `scale` path was not covered by that change. Unlike the WMF case, where the file-controlled `_inch` makes the ratio unbounded, the EPS multiplier is fixed by the application.\n\n## Reproducing\n\nRun `repro` against the installed Pillow. Ghostscript does not need to be installed: the script sets `EpsImagePlugin.gs_binary = \"gs\"` so that `has_ghostscript()` skips its `gs --version` probe, and replaces `subprocess.check_call` with a function that records the command line Pillow builds and then raises `OSError`, so nothing is actually rendered.\n\nIt writes a 76-byte EPS declaring `%%BoundingBox: 0 0 9000 9000` (the example above without the drawing line; 81 Mpixel, below the default `MAX_IMAGE_PIXELS` of 89,478,485) and turns `DecompressionBombWarning` into an error, so any bomb check \u2014 warning or hard error \u2014 counts. It then calls `Image.open()` and `im.load(scale=2)`. `Image.open()` accepts the file and `load(scale=2)` reaches the intercepted Ghostscript call with `-g18000x18000` (324,000,000 pixels, 3.6\u00d7 `MAX_IMAGE_PIXELS`, a 972 MB `pnmraw` output with real Ghostscript). The script prints the geometry it captured.\n\nIt prints `BUG` when Ghostscript was invoked with a `-g` geometry above `2*MAX_IMAGE_PIXELS` (178,956,970) and no decompression-bomb check fired before that call; otherwise it prints `OK`. With the attached patch applied, `load(scale=2)` raises `DecompressionBombError` before Ghostscript is called and the script prints `OK`.\n\n## Suggested fix\n\nThe attached patch checks the scaled size in `Ghostscript()` right after the scaled `width`/`height` are computed (`src/PIL/EpsImagePlugin.py:93-94`) and before the `gs` command is built, mirroring `WmfStubImageFile.load`:\n\n```diff\n--- a/src/PIL/EpsImagePlugin.py\n+++ b/src/PIL/EpsImagePlugin.py\n@@ -92,6 +92,7 @@ def Ghostscript(\n     scale = int(scale) or 1\n     width = size[0] * scale\n     height = size[1] * scale\n+    Image._decompression_bomb_check((width, height))\n     # resolution is dependent on bbox and size\n     res_x = 72.0 * width / (bbox[2] - bbox[0])\n     res_y = 72.0 * height / (bbox[3] - bbox[1])\n```\n\n`load(scale=N)` now raises `DecompressionBombError` / emits `DecompressionBombWarning` under the same `MAX_IMAGE_PIXELS` thresholds `Image.open()` applies, before Ghostscript runs instead of after. Placing the check in `Ghostscript()` rather than in `EpsImageFile.load()` is the single point where the rendered extent is decided, so it also covers direct callers of the module-level function. With the patch applied to a clean checkout the reproducer prints `OK` and `Tests/test_file_eps.py` passes. One cosmetic side effect: at `scale=1` the check re-emits the `DecompressionBombWarning` that `Image.open()` already issued for sizes between 1\u00d7 and 2\u00d7 the limit; guarding the call with `if scale \u003e 1:` would avoid the duplicate.\n\nThe patch also adds `test_load_scale_decompression_bomb` to `Tests/test_file_eps.py`, in the style of the WMF test: it sets `MAX_IMAGE_PIXELS` to `im.width * im.height` and expects `im.load(scale=2)` to raise `DecompressionBombError`. Like the rest of that file it is skipped without Ghostscript, because `has_ghostscript()` is consulted at the top of `Ghostscript()`; moving the check above that call would let the test run without it.\n\n## The patch\n\nAdd decompression bomb check on the scaled size in EpsImagePlugin.Ghostscript() before Ghostscript is invoked\n\nApplies to `src/PIL/EpsImagePlugin.py` at the commit above.\n\n```diff\ndiff --git a/Tests/test_file_eps.py b/Tests/test_file_eps.py\nindex 70eced62a..de331d97f 100644\n--- a/Tests/test_file_eps.py\n+++ b/Tests/test_file_eps.py\n@@ -98,6 +98,14 @@ def test_sanity(filename: str, size: tuple[int, int], scale: int) -\u003e None:\n         assert image.format == \"EPS\"\n \n \n+@pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason=\"Ghostscript not available\")\n+def test_load_scale_decompression_bomb(monkeypatch: pytest.MonkeyPatch) -\u003e None:\n+    with Image.open(FILE1) as im:\n+        monkeypatch.setattr(Image, \"MAX_IMAGE_PIXELS\", im.width * im.height)\n+        with pytest.raises(Image.DecompressionBombError):\n+            im.load(scale=2)\n+\n+\n @pytest.mark.skipif(not HAS_GHOSTSCRIPT, reason=\"Ghostscript not available\")\n def test_load() -\u003e None:\n     with Image.open(FILE1) as im:\ndiff --git a/src/PIL/EpsImagePlugin.py b/src/PIL/EpsImagePlugin.py\nindex 5eaefe339..ccc6f1d85 100644\n--- a/src/PIL/EpsImagePlugin.py\n+++ b/src/PIL/EpsImagePlugin.py\n@@ -92,6 +92,7 @@ def Ghostscript(\n     scale = int(scale) or 1\n     width = size[0] * scale\n     height = size[1] * scale\n+    Image._decompression_bomb_check((width, height))\n     # resolution is dependent on bbox and size\n     res_x = 72.0 * width / (bbox[2] - bbox[0])\n     res_y = 72.0 * height / (bbox[3] - bbox[1])\n```\n\n## The reproducer\n\n\u003cdetails\u003e\n\u003csummary\u003eReproducer \u2014 \u003ccode\u003erepro\u003c/code\u003e, 1,845 bytes (click to open)\u003c/summary\u003e\n\nIts last line is `BUG` when the issue triggers and `OK` when it does not. Re-run on a clean build of that commit it printed `BUG`.\n\n```python\n#!/usr/bin/env python3\n# EpsImagePlugin.Ghostscript(): load(scale=N) hands gs a -g geometry of\n# (W*N)x(H*N) with no _decompression_bomb_check on the scaled size; only the\n# unscaled WxH was checked by Image.open(). gs is not installed here, so we\n# set gs_binary and intercept subprocess.check_call to read the argv Pillow builds.\nimport os, subprocess, tempfile, warnings\nfrom PIL import Image, EpsImagePlugin\n\nEpsImagePlugin.gs_binary = \"gs\"  # skip the `gs --version` probe\npath = os.path.join(tempfile.mkdtemp(), \"a.eps\")\nwith open(path, \"w\") as f:  # 9000x9000 = 81 Mpx \u003c MAX_IMAGE_PIXELS (89.5 Mpx)\n    f.write(\"%!PS-Adobe-3.0 EPSF-3.0\\n%%BoundingBox: 0 0 9000 9000\\n%%EndComments\\nshowpage\\n\")\n\ncalls = []\ndef fake_check_call(cmd, **kw):\n    calls.append(cmd)\n    raise OSError(\"gs intercepted\")  # stop here; we only need the argv\nsubprocess.check_call = fake_check_call\n\nhard = 2 * Image.MAX_IMAGE_PIXELS\nbomb_before_gs = False\nwith warnings.catch_warnings():\n    warnings.simplefilter(\"error\", Image.DecompressionBombWarning)\n    try:\n        with Image.open(path) as im:\n            print(\"Image.open accepted\", os.path.getsize(path), \"byte EPS, size\", im.size)\n            im.load(scale=2)\n    except (Image.DecompressionBombError, Image.DecompressionBombWarning) as e:\n        bomb_before_gs = not calls\n        print(\"bomb check fired\", \"before\" if bomb_before_gs else \"after\", \"gs:\", e)\n    except OSError as e:\n        print(\"load() reached gs:\", e)\n\nover = False\nfor c in calls:\n    g = next(a for a in c if a.startswith(\"-g\"))[2:]\n    w, h = map(int, g.split(\"x\"))\n    over |= w * h \u003e hard\n    print(f\"gs argv geometry -g{g} = {w*h} px ({w*h/Image.MAX_IMAGE_PIXELS:.1f}x MAX_IMAGE_PIXELS, \"\n          f\"hard limit {hard}); pnmraw output would be {w*h*3} bytes\")\nprint(\"BUG\" if calls and over and not bomb_before_gs else \"OK\")\n```\n\u003c/details\u003e\n\n---",
  "id": "GHSA-vx6w-vv9f-6gvg",
  "modified": "2026-10-20T20:53:21Z",
  "published": "2026-10-20T20:53:21Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/python-pillow/Pillow/security/advisories/GHSA-vx6w-vv9f-6gvg"
    },
    {
      "type": "WEB",
      "url": "https://github.com/python-pillow/Pillow/commit/3e8cc105588d1dfe062fcada0b6058c1b5f14b65"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/python-pillow/Pillow"
    },
    {
      "type": "WEB",
      "url": "https://github.com/python-pillow/Pillow/releases/tag/13.0.0"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Pillow: EPS load(scale) lets Ghostscript render past the decompression bomb limit"
}

GHSA-VXPW-J846-P89Q

Vulnerability from github – Published: 2026-06-19 14:22 – Updated: 2026-06-19 14:22
VLAI
Summary
undici WebSocket client vulnerable to denial of service via fragment count bypass
Details

Impact

The undici WebSocket client enforces maxPayloadSize on the cumulative byte count of fragments in a message but does not enforce a limit on the number of fragments. A malicious WebSocket server can stream many small or empty continuation frames that each pass per-frame and cumulative-size validation, collectively causing unbounded memory growth in the client process. The result is memory exhaustion and a denial of service.

Affected applications are those using the undici WebSocket client (new WebSocket(...)) or the WebSocketStream API that can be induced to connect to an attacker-controlled or compromised WebSocket endpoint.

All releases starting at undici 6.17.0 are affected.

Patches

Upgrade to undici v6.27.0, v7.28.0 or v8.5.0.

Workarounds

No workaround is available. The fix must be applied through an upgrade.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "npm",
        "name": "undici"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "6.27.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "undici"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "7.0.0"
            },
            {
              "fixed": "7.28.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "package": {
        "ecosystem": "npm",
        "name": "undici"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "8.0.0"
            },
            {
              "fixed": "8.5.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-12151"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-400",
      "CWE-770"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-19T14:22:01Z",
    "nvd_published_at": "2026-06-17T17:16:42Z",
    "severity": "HIGH"
  },
  "details": "## Impact\n\nThe undici WebSocket client enforces `maxPayloadSize` on the cumulative byte count of fragments in a message but does not enforce a limit on the number of fragments. A malicious WebSocket server can stream many small or empty continuation frames that each pass per-frame and cumulative-size validation, collectively causing unbounded memory growth in the client process. The result is memory exhaustion and a denial of service.\n\nAffected applications are those using the undici WebSocket client (`new WebSocket(...)`) or the `WebSocketStream` API that can be induced to connect to an attacker-controlled or compromised WebSocket endpoint.\n\nAll releases starting at undici 6.17.0 are affected.\n\n## Patches\n\nUpgrade to undici v6.27.0, v7.28.0 or v8.5.0.\n\n## Workarounds\n\nNo workaround is available. The fix must be applied through an upgrade.",
  "id": "GHSA-vxpw-j846-p89q",
  "modified": "2026-06-19T14:22:01Z",
  "published": "2026-06-19T14:22:01Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/nodejs/undici/security/advisories/GHSA-vxpw-j846-p89q"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-12151"
    },
    {
      "type": "WEB",
      "url": "https://cna.openjsf.org/security-advisories.html"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/nodejs/undici"
    }
  ],
  "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 WebSocket client vulnerable to denial of service via fragment count bypass"
}

GHSA-VXQ7-64XX-V4GW

Vulnerability from github – Published: 2026-09-30 14:46 – Updated: 2026-09-30 14:46
VLAI
Summary
urllib3: HTTPResponse.stream()/read_chunked() buffers an unbounded chunk-size line into memory
Details

Impact

urllib3's streaming API is designed for efficiently handling large HTTP responses by reading the content in chunks, rather than loading the entire response body into memory at once. When decoding a chunked-transfer-encoded response, this API reads each chunk's size field by buffering until it sees \n or EOF.

A malicious HTTP server can return Transfer-Encoding: chunked and then send a very long run of bytes without any newline, causing the streaming client to buffer that entire run before urllib3 can reject the chunk size as invalid and allocate more memory than intended.

To fix the issue, we'll reject chunk-size fields larger than 65536 bytes, as already done in the non-streaming case, which is currently handled by the Python standard library. Note that this only applies to reading the chunk-size field, not the chunk data, which is already handled correctly. Thus, there shouldn't be any impact for non-malicious servers.

Affected usages

Applications and libraries using urllib3 versions earlier than 2.8.0 may be affected when streaming a chunked response from untrusted sources. Specifically, this affects the read_chunked() and stream() methods of the HTTPResponse object.

This also affects requests streaming API, which uses urllib3 under the hood.

Remediation

Upgrade to urllib3 version 2.8.0 or later, where chunk-size fields larger than 65536 will be rejected. If upgrading is not immediately possible, consider reading the response at once using the read() method.

Show details on source website

{
  "affected": [
    {
      "package": {
        "ecosystem": "PyPI",
        "name": "urllib3"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "1.10.3"
            },
            {
              "fixed": "2.8.0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-97689"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-770"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-09-30T14:46:18Z",
    "nvd_published_at": "2026-09-29T16:17:18Z",
    "severity": "HIGH"
  },
  "details": "## Impact\n\nurllib3\u0027s [streaming API](https://urllib3.readthedocs.io/en/2.7.0/advanced-usage.html#streaming-and-i-o) is designed for efficiently handling large HTTP responses by reading the content in chunks, rather than loading the entire response body into memory at once. When decoding a [chunked-transfer-encoded response](https://httpwg.org/specs/rfc9112.html#chunked.encoding), this API reads each chunk\u0027s size field by buffering until it sees `\\n` or EOF.\n\nA malicious HTTP server can return `Transfer-Encoding: chunked` and then send a very long run of bytes without any newline, causing the streaming client to buffer that entire run before urllib3 can reject the chunk size as invalid and allocate more memory than intended.\n\nTo fix the issue, we\u0027ll reject chunk-size fields larger than 65536 bytes, as already done in the non-streaming case, which is currently handled by the Python standard library. Note that this only applies to reading the chunk-size field, not the chunk data, which is already handled correctly. Thus, there shouldn\u0027t be any impact for non-malicious servers.\n\n## Affected usages\n\nApplications and libraries using urllib3 versions earlier than 2.8.0 may be affected when streaming a chunked response from untrusted sources. Specifically, this affects the [read_chunked()](https://urllib3.readthedocs.io/en/stable/reference/urllib3.response.html#urllib3.response.BaseHTTPResponse.read_chunked) and [stream()](https://urllib3.readthedocs.io/en/stable/reference/urllib3.response.html#urllib3.response.BaseHTTPResponse.stream) methods of the HTTPResponse object.\n\nThis also affects requests streaming API, which uses urllib3 under the hood.\n\n## Remediation\n\nUpgrade to urllib3 version 2.8.0 or later, where chunk-size fields larger than 65536 will be rejected. If upgrading is not immediately possible, consider reading the response at once using the [read()](https://urllib3.readthedocs.io/en/stable/reference/urllib3.response.html#urllib3.response.BaseHTTPResponse.read) method.",
  "id": "GHSA-vxq7-64xx-v4gw",
  "modified": "2026-09-30T14:46:18Z",
  "published": "2026-09-30T14:46:18Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/urllib3/urllib3/security/advisories/GHSA-vxq7-64xx-v4gw"
    },
    {
      "type": "ADVISORY",
      "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-97689"
    },
    {
      "type": "WEB",
      "url": "https://github.com/urllib3/urllib3/commit/cd770b059b543be29298ea5c52afb0b1b090f5ed"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/urllib3/urllib3"
    },
    {
      "type": "WEB",
      "url": "https://github.com/urllib3/urllib3/releases/tag/2.8.0"
    }
  ],
  "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:H",
      "type": "CVSS_V4"
    }
  ],
  "summary": "urllib3: HTTPResponse.stream()/read_chunked() buffers an unbounded chunk-size line into memory"
}

Mitigation
Requirements

Clearly specify the minimum and maximum expectations for capabilities, and dictate which behaviors are acceptable when resource allocation reaches limits.

Mitigation
Architecture and Design

Limit the amount of resources that are accessible to unprivileged users. Set per-user limits for resources. Allow the system administrator to define these limits. Be careful to avoid CWE-410.

Mitigation
Architecture and Design

Design throttling mechanisms into the system architecture. The best protection is to limit the amount of resources that an unauthorized user can cause to be expended. A strong authentication and access control model will help prevent such attacks from occurring in the first place, and it will help the administrator to identify who is committing the abuse. The login application should be protected against DoS attacks as much as possible. Limiting the database access, perhaps by caching result sets, can help minimize the resources expended. To further limit the potential for a DoS attack, consider tracking the rate of requests received from users and blocking requests that exceed a defined rate threshold.

Mitigation MIT-5
Implementation

Strategy: Input Validation

  • Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does.
  • When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue."
  • Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylists can be useful for detecting potential attacks or determining which inputs are so malformed that they should be rejected outright.
Mitigation MIT-15
Architecture and Design

For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.

Mitigation
Architecture and Design
  • Mitigation of resource exhaustion attacks requires that the target system either:
  • The first of these solutions is an issue in itself though, since it may allow attackers to prevent the use of the system by a particular valid user. If the attacker impersonates the valid user, they may be able to prevent the user from accessing the server in question.
  • The second solution can be difficult to effectively institute -- and even when properly done, it does not provide a full solution. It simply requires more resources on the part of the attacker.
  • recognizes the attack and denies that user further access for a given amount of time, typically by using increasing time delays
  • uniformly throttles all requests in order to make it more difficult to consume resources more quickly than they can again be freed.
Mitigation
Architecture and Design

Ensure that protocols have specific limits of scale placed on them.

Mitigation MIT-38.1
Architecture and Design Implementation
  • If the program must fail, ensure that it fails gracefully (fails closed). There may be a temptation to simply let the program fail poorly in cases such as low memory conditions, but an attacker may be able to assert control before the software has fully exited. Alternately, an uncontrolled failure could cause cascading problems with other downstream components; for example, the program could send a signal to a downstream process so the process immediately knows that a problem has occurred and has a better chance of recovery.
  • Ensure that all failures in resource allocation place the system into a safe posture.
Mitigation MIT-47
Operation Architecture and Design

Strategy: Resource Limitation

  • Use quotas or other resource-limiting settings provided by the operating system or environment. For example, when managing system resources in POSIX, setrlimit() can be used to set limits for certain types of resources, and getrlimit() can determine how many resources are available. However, these functions are not available on all operating systems.
  • When the current levels get close to the maximum that is defined for the application (see CWE-770), then limit the allocation of further resources to privileged users; alternately, begin releasing resources for less-privileged users. While this mitigation may protect the system from attack, it will not necessarily stop attackers from adversely impacting other users.
  • Ensure that the application performs the appropriate error checks and error handling in case resources become unavailable (CWE-703).
CAPEC-125: Flooding

An adversary consumes the resources of a target by rapidly engaging in a large number of interactions with the target. This type of attack generally exposes a weakness in rate limiting or flow. When successful this attack prevents legitimate users from accessing the service and can cause the target to crash. This attack differs from resource depletion through leaks or allocations in that the latter attacks do not rely on the volume of requests made to the target but instead focus on manipulation of the target's operations. The key factor in a flooding attack is the number of requests the adversary can make in a given period of time. The greater this number, the more likely an attack is to succeed against a given target.

CAPEC-130: Excessive Allocation

An adversary causes the target to allocate excessive resources to servicing the attackers' request, thereby reducing the resources available for legitimate services and degrading or denying services. Usually, this attack focuses on memory allocation, but any finite resource on the target could be the attacked, including bandwidth, processing cycles, or other resources. This attack does not attempt to force this allocation through a large number of requests (that would be Resource Depletion through Flooding) but instead uses one or a small number of requests that are carefully formatted to force the target to allocate excessive resources to service this request(s). Often this attack takes advantage of a bug in the target to cause the target to allocate resources vastly beyond what would be needed for a normal request.

CAPEC-147: XML Ping of the Death

An attacker initiates a resource depletion attack where a large number of small XML messages are delivered at a sufficiently rapid rate to cause a denial of service or crash of the target. Transactions such as repetitive SOAP transactions can deplete resources faster than a simple flooding attack because of the additional resources used by the SOAP protocol and the resources necessary to process SOAP messages. The transactions used are immaterial as long as they cause resource utilization on the target. In other words, this is a normal flooding attack augmented by using messages that will require extra processing on the target.

CAPEC-197: Exponential Data Expansion

An adversary submits data to a target application which contains nested exponential data expansion to produce excessively large output. Many data format languages allow the definition of macro-like structures that can be used to simplify the creation of complex structures. However, this capability can be abused to create excessive demands on a processor's CPU and memory. A small number of nested expansions can result in an exponential growth in demands on memory.

CAPEC-229: Serialized Data Parameter Blowup

This attack exploits certain serialized data parsers (e.g., XML, YAML, etc.) which manage data in an inefficient manner. The attacker crafts an serialized data file with multiple configuration parameters in the same dataset. In a vulnerable parser, this results in a denial of service condition where CPU resources are exhausted because of the parsing algorithm. The weakness being exploited is tied to parser implementation and not language specific.

CAPEC-230: Serialized Data with Nested Payloads

Applications often need to transform data in and out of a data format (e.g., XML and YAML) by using a parser. It may be possible for an adversary to inject data that may have an adverse effect on the parser when it is being processed. Many data format languages allow the definition of macro-like structures that can be used to simplify the creation of complex structures. By nesting these structures, causing the data to be repeatedly substituted, an adversary can cause the parser to consume more resources while processing, causing excessive memory consumption and CPU utilization.

CAPEC-231: Oversized Serialized Data Payloads

An adversary injects oversized serialized data payloads into a parser during data processing to produce adverse effects upon the parser such as exhausting system resources and arbitrary code execution.

CAPEC-469: HTTP DoS

An attacker performs flooding at the HTTP level to bring down only a particular web application rather than anything listening on a TCP/IP connection. This denial of service attack requires substantially fewer packets to be sent which makes DoS harder to detect. This is an equivalent of SYN flood in HTTP. The idea is to keep the HTTP session alive indefinitely and then repeat that hundreds of times. This attack targets resource depletion weaknesses in web server software. The web server will wait to attacker's responses on the initiated HTTP sessions while the connection threads are being exhausted.

CAPEC-482: TCP Flood

An adversary may execute a flooding attack using the TCP protocol with the intent to deny legitimate users access to a service. These attacks exploit the weakness within the TCP protocol where there is some state information for the connection the server needs to maintain. This often involves the use of TCP SYN messages.

CAPEC-486: UDP Flood

An adversary may execute a flooding attack using the UDP protocol with the intent to deny legitimate users access to a service by consuming the available network bandwidth. Additionally, firewalls often open a port for each UDP connection destined for a service with an open UDP port, meaning the firewalls in essence save the connection state thus the high packet nature of a UDP flood can also overwhelm resources allocated to the firewall. UDP attacks can also target services like DNS or VoIP which utilize these protocols. Additionally, due to the session-less nature of the UDP protocol, the source of a packet is easily spoofed making it difficult to find the source of the attack.

CAPEC-487: ICMP Flood

An adversary may execute a flooding attack using the ICMP protocol with the intent to deny legitimate users access to a service by consuming the available network bandwidth. A typical attack involves a victim server receiving ICMP packets at a high rate from a wide range of source addresses. Additionally, due to the session-less nature of the ICMP protocol, the source of a packet is easily spoofed making it difficult to find the source of the attack.

CAPEC-488: HTTP Flood

An adversary may execute a flooding attack using the HTTP protocol with the intent to deny legitimate users access to a service by consuming resources at the application layer such as web services and their infrastructure. These attacks use legitimate session-based HTTP GET requests designed to consume large amounts of a server's resources. Since these are legitimate sessions this attack is very difficult to detect.

CAPEC-489: SSL Flood

An adversary may execute a flooding attack using the SSL protocol with the intent to deny legitimate users access to a service by consuming all the available resources on the server side. These attacks take advantage of the asymmetric relationship between the processing power used by the client and the processing power used by the server to create a secure connection. In this manner the attacker can make a large number of HTTPS requests on a low provisioned machine to tie up a disproportionately large number of resources on the server. The clients then continue to keep renegotiating the SSL connection. When multiplied by a large number of attacking machines, this attack can result in a crash or loss of service to legitimate users.

CAPEC-490: Amplification

An adversary may execute an amplification where the size of a response is far greater than that of the request that generates it. The goal of this attack is to use a relatively few resources to create a large amount of traffic against a target server. To execute this attack, an adversary send a request to a 3rd party service, spoofing the source address to be that of the target server. The larger response that is generated by the 3rd party service is then sent to the target server. By sending a large number of initial requests, the adversary can generate a tremendous amount of traffic directed at the target. The greater the discrepancy in size between the initial request and the final payload delivered to the target increased the effectiveness of this attack.

CAPEC-491: Quadratic Data Expansion

An adversary exploits macro-like substitution to cause a denial of service situation due to excessive memory being allocated to fully expand the data. The result of this denial of service could cause the application to freeze or crash. This involves defining a very large entity and using it multiple times in a single entity substitution. CAPEC-197 is a similar attack pattern, but it is easier to discover and defend against. This attack pattern does not perform multi-level substitution and therefore does not obviously appear to consume extensive resources.

CAPEC-493: SOAP Array Blowup

An adversary may execute an attack on a web service that uses SOAP messages in communication. By sending a very large SOAP array declaration to the web service, the attacker forces the web service to allocate space for the array elements before they are parsed by the XML parser. The attacker message is typically small in size containing a large array declaration of say 1,000,000 elements and a couple of array elements. This attack targets exhaustion of the memory resources of the web service.

CAPEC-494: TCP Fragmentation

An adversary may execute a TCP Fragmentation attack against a target with the intention of avoiding filtering rules of network controls, by attempting to fragment the TCP packet such that the headers flag field is pushed into the second fragment which typically is not filtered.

CAPEC-495: UDP Fragmentation

An attacker may execute a UDP Fragmentation attack against a target server in an attempt to consume resources such as bandwidth and CPU. IP fragmentation occurs when an IP datagram is larger than the MTU of the route the datagram has to traverse. Typically the attacker will use large UDP packets over 1500 bytes of data which forces fragmentation as ethernet MTU is 1500 bytes. This attack is a variation on a typical UDP flood but it enables more network bandwidth to be consumed with fewer packets. Additionally it has the potential to consume server CPU resources and fill memory buffers associated with the processing and reassembling of fragmented packets.

CAPEC-496: ICMP Fragmentation

An attacker may execute a ICMP Fragmentation attack against a target with the intention of consuming resources or causing a crash. The attacker crafts a large number of identical fragmented IP packets containing a portion of a fragmented ICMP message. The attacker these sends these messages to a target host which causes the host to become non-responsive. Another vector may be sending a fragmented ICMP message to a target host with incorrect sizes in the header which causes the host to hang.

CAPEC-528: XML Flood

An adversary may execute a flooding attack using XML messages with the intent to deny legitimate users access to a web service. These attacks are accomplished by sending a large number of XML based requests and letting the service attempt to parse each one. In many cases this type of an attack will result in a XML Denial of Service (XDoS) due to an application becoming unstable, freezing, or crashing.