Skip to content

imgproxy has integer overflow in imgproxy ICO loader that causes denial of service and may permit remote code execution

Critical severity GitHub Reviewed Published Oct 6, 2026 in imgproxy/imgproxy • Updated Oct 30, 2026

Package

gomod github.com/imgproxy/imgproxy (Go)

Affected versions

>= 4.0.0, < 4.0.16

Patched versions

4.0.16
gomod github.com/imgproxy/imgproxy/v2 (Go)
>= 4.0.0, < 4.0.16
4.0.16
gomod github.com/imgproxy/imgproxy/v3 (Go)
>= 4.0.0, < 4.0.16
4.0.16

Description

Summary

The ICO loader allocates data_size + BMP_FILE_HEADER_LEN bytes after reading a 32-bit attacker-controlled data_size. For data_size > UINT32_MAX - BMP_FILE_HEADER_LEN, the addition wraps before allocation. imgproxy then writes the ICO prefix and reads up to the original declared size starting 14 bytes into the undersized allocation. A network client can turn this heap overflow into remote denial of service or remote code execution.

Technical details

The vulnerable path is in vips/icoload.c at commit f4fedbb:

uint32_t data_size = GUINT32_FROM_LE(largest_image_header.data_size);

VipsPel *data = (VipsPel *) VIPS_MALLOC(NULL, data_size + BMP_FILE_HEADER_LEN);
void *actual_data = data + BMP_FILE_HEADER_LEN;

if (vips_foreign_load_read_full(ico->source, actual_data, data_size) <= 0) {
  vips_error("vips_foreign_load_ico_header", "unable to read ICO image data from the source");
  return -1;
}

The crafted directory entry contains:

data_size       = 0xfffffff5 (4294967285)
data_offset     = 22
BMP header size = 14
32-bit result   = (0xfffffff5 + 14) mod 2^32 = 3

The allocation is therefore three bytes. actual_data points 14 bytes after the allocation base. The fixture contains 64 bytes after the ICO header, so the source callback copies those 64 bytes to an invalid destination before it can report that the declared multi-gigabyte payload is incomplete.

The complete source-to-sink path is:

  1. Attacker-controlled bytes begin with the ICO magic 00 00 01 00.
  2. imgproxy identifies the source as ICO and dispatches it to vips_icoload_source_go.
  3. vips_foreign_load_ico_header reads the attacker-controlled data_size.
  4. The 32-bit addition wraps, and VIPS_MALLOC receives the value three.
  5. vips_foreign_load_read_full passes the original data_size to the Go source callback.
  6. The callback writes the available source bytes through the invalid pointer, corrupting the process heap.

Impact

A crafted image can terminate the imgproxy process handling it or potentially lead to remote code execution due to heap corruption.

References

@DarthSim DarthSim published to imgproxy/imgproxy Oct 6, 2026
Published to the GitHub Advisory Database Oct 30, 2026
Reviewed Oct 30, 2026
Last updated Oct 30, 2026

Severity

Critical

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

EPSS score

Weaknesses

Heap-based Buffer Overflow

A heap overflow condition is a buffer overflow, where the buffer that can be overwritten is allocated in the heap portion of memory, generally meaning that the buffer was allocated using a routine such as malloc(). Learn more on MITRE.

Integer Overflow or Wraparound

The product performs a calculation that can produce an integer overflow or wraparound when the logic assumes that the resulting value will always be larger than the original value. This occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may become a very small or negative number. Learn more on MITRE.

CVE ID

No known CVE

GHSA ID

GHSA-hff9-5pqw-6w9f

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.