GHSA-8q6g-vjhf-jp8m: High severity pip/psd-tools vulnerability

Published Sep 22, 2026
·
Updated

Summary PSDImage.composite() (and .numpy()) allocate the output image buffer from the PSD's header geometry (width × height × channels × depth, and per-layer rectangles) before validating those values against the actual file contents. A tiny crafted PSD declaring huge dimensions causes a multi-gigabyte allocation. Critically, composite() then returns a (black) image with only a warning, no exception is raised, so a caller cannot detect or guard against it.

Impact On psd-tools 1.17.2 (latest), default usage, a 49-byte PSD makes composite() commit ~3 GB and return successfully (warning only); .numpy() reaches ~7.5 GB, and the per-layer rectangle is a second lever (up to ~32 GB), all from an input under 100 bytes (input-to-commit amplification over 1000×). Because the buffer is committed before validation and no exception is thrown, any service that composites untrusted PSDs is exposed to denial of service: on a host with less RAM than the attacker-declared geometry the allocation is an unrecoverable OOM-kill.

Steps to reproduce python pip install psd-tools==1.17.2 from psdtools import PSDImage psd = PSDImage.open("psd-psdtools-grammar-d23.psd") psd.composite() # commits ~3 GB from a 49-byte file and returns (warning only)

PoC (49 bytes), reconstruct with: sh base64 -d > psd-psdtools-grammar-d23.psd <<'EOF' OEJQUwABAAAAAAAAAAYAACg4AAAXTAAIAAMAAAAAAAAAAAAAAAAAAUNIUIFU+yQtDw== EOF Verify: 7d8ebf03a54393cb0359ecf4b676d1b08c9a8c6afdd06671ef406d6893cce826 psd-psdtools-grammar-d23.psd

Root cause The composite/numpy buffer is sized from the declared image (and per-layer) dimensions and channel/depth without checking them against the available data length or a sane maximum.

Suggested fix Validate the declared dimensions, channel count, and per-layer rectangles against the actual file length (and a configurable maximum pixel/byte budget) before allocating; raise an error on overflow instead of committing the buffer and returning a black image.

Affected Software

1 affected componentFixes available
pip/psd-tools<1.17.4
1.17.4

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/psd-tools to a version that resolves this vulnerability.

    Fixed in 1.17.4
  2. Compensating control

    Before allocating buffers in PSDImage.composite() or .numpy(), validate the declared image dimensions, channel count, bit depth, and per-layer rectangles against the actual file length and a configurable maximum pixel/byte budget; raise an error on overflow or invalid values instead of committing the buffer and returning a black image.

Event History

Sep 22, 2026
Advisory Published
via GitHub·07:45 PM
Data Sourced
via GitHub·07:45 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Which deployments are exposed?

Any service that composites untrusted PSD files is exposed. The issue occurs with default usage in psd-tools 1.17.2, without requiring credentials or user interaction.

2

What does an attacker need to do to trigger the denial of service?

An attacker only needs to supply a crafted PSD with declared image geometry or layer rectangles that are much larger than its actual contents. Files under 100 bytes can cause multi-gigabyte memory commitments.

3

How can an application recognize an attempted exploit?

A call to composite() may return a black image and emit only a warning rather than raising an exception. The allocation occurs before geometry is validated, so callers cannot rely on an exception to prevent the memory commitment.

4

What can be done if updating is not immediately possible?

Do not composite PSD files from untrusted sources. Where untrusted uploads must be accepted, isolate PSD processing and enforce memory limits so an oversized allocation cannot exhaust the main service host.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203