Unbounded memory allocation in ICO loader allows unauthenticated memory-exhaustion DoS via crafted data_size field
Résumé
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 wor...
Résumé IA
Rédigé par une IA externe ; il peut contenir des erreurs. Vérifiez la description d'origine et les références ci-dessous avant d'agir.
imgproxyのICOローダーで、細工されたICOファイルによって約4GBのメモリ割り当てが発生し、認証なしでメモリを枯渇させられるおそれがあります。影響を受けるのは最新版v4.0.15および3.3.xシリーズで、v4.0.16以降に更新してください。
Paquets affectés
| Écosystème | Paquet | Concernées | Corrigé |
|---|---|---|---|
| github.com/darthsim/imgproxy |
>= 3.3.0, <= 4.0.15 |
>= 4.0.16 |
Description d'origine La description telle que publiée par la source (souvent en anglais).
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
# 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(' HTTP 500 (worker survives, but each request burns ~4GB
# transiently — repeatable memor…
Source: GitHub Repository Security Advisories (Game のスタック) GitHub Advisory OSV
Références
- GITHUB_REPO_ADVISORY imgproxy/imgproxy