NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
.NET
.NET NuGet
Not in CISA KEV
MEDIUM severity

CVE-2025-62594 — Magick.NET-Q16-x64

MEDIUMFix: ImageMagick/ImageMagick@7b47fe3

CVE-2025-62594 is a medium-severity (CVSS 4.7) Buffer Overflow vulnerability in Magick.NET-Q16-x64. The records list no fixed version yet; check the vendor advisory below and apply the mitigations in the meantime.

ImageMagick CLAHE : Unsigned underflow and division-by-zero lead to OOB pointer arithmetic and process crash (DoS)

Also known asGHSA-wpp4-vqfq-v4hp
Published
Updated
Affected
12 pkgs
Patched
See advisory
Exploits
None indexed
Exploitation data as of Nov 6, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for CVE-2025-62594.

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs31th percentile — riskier than 31% of all scored CVEsHighest risk
0.00%0.29%0.58%0.87%0.0%0.4%May 26Sep 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

12 pkgs affected
.NETMagick.NET-Q16-x64.NETMagick.NET-Q8-x64.NETMagick.NET-Q16-HDRI-x64.NETMagick.NET-Q8-OpenMP-x64.NETMagick.NET-Q16-HDRI-OpenMP-x64.NETMagick.NET-Q16-OpenMP-x64.NETMagick.NET-Q8-arm64.NETMagick.NET-Q16-arm64+4 more

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects NuGet packages — download data is not available via public APIs for these ecosystems.

Description

Summary

A single root cause in the CLAHE implementation — tile width/height becoming zero — produces two distinct but related unsafe behaviors. Vulnerabilities exists in the CLAHEImage() function of ImageMagick’s MagickCore/enhance.c.

  1. Unsigned integer underflow → out-of-bounds pointer arithmetic (OOB): when tile_info.height == 0, the expression tile_info.height - 1 (unsigned) wraps to a very large value; using that value in pointer arithmetic yields a huge offset and OOB memory access (leading to memory corruption, SIGSEGV, or resource exhaustion).
  2. Division/modulus by zero: where code performs ... / tile_info.width or ... % tile_info.height without re-checking for zero, causing immediate division-by-zero crashes under sanitizers or abort at runtime.

Both behaviors are triggered by the same invalid tile condition (e.g., CLI exact -clahe 0x0! or automatic tile derivation dim >> 3 == 0 for very small images).


Details

Unsigned underflow(can lea to OOB)

  • Location: MagickCore/enhance.c, around line 609

  • Version tested: 7.1.2-8 (local ASan(undefined). /UBSan build)

  • Vulnerable code

    enhance.c: 609

    p += (ptrdiff_t) clahe_info->width * (tile.height - 1);
    
  • Root Cause

    • If tile.height == 0, then (tile.height - 1) underflows to UINT_MAX.
    • Multiplication with clahe_info->width yields a huge value close to SIZE_MAX.
    • Adding this to p causes pointer arithmetic underflow.

Division-by-zero

  • File / Location: MagickCore/enhance.c, around line 669

  • Version tested: 7.1.2-8 (local ASan(undefined). /UBSan build)

  • vulnerable code

    enhance.c: 669-673

     if ((image->columns % tile_info.width) != 0)
        tile_info.x=(ssize_t) (tile_info.width-(image->columns % tile_info.width));
      tile_info.y=0;
      if ((image->rows % tile_info.height) != 0)
        tile_info.y=(ssize_t) (tile_info.height-(image->rows % tile_info.height));
    
  • Root cause

    Missing input validation / bounds checks after computing default tile dimensions:

    If either tile_info.width or tile_info.height is 0, this triggers a division by zero. Zeros can reach this point through:

    1. Exact tiles: CLI clahe 0x0! (the ! forces zero to be used verbatim).
    2. Auto tiles on tiny images: When a requested tile is 0 (no !), the code derives a default from the image size (e.g., dim >> 3). For images with dim < 8, this result is 0 unless clamped.

Reproduction

Unsigned underflow

Environment

Built with AddressSanitizer and UndefinedBehaviorSanitizer enabled.

export UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
export ASAN_OPTIONS=abort_on_error=1:allocator_may_return_null=1:detect_leaks=0

Command

./magick xc:black -clahe 0x0 null:

Output

MagickCore/enhance.c:609:6: runtime error: addition of unsigned offset overflowed
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior MagickCore/enhance.c:609:6 in CLAHEImage

./magick -size 10x10 xc:black -clahe 0x0 null:

<img width="1068" height="64" alt="image" src="https://github.com/user-attachments/assets/cd9637ee-1d03-4066-834d-fda22410dd8b" />

memory region corruption.

./magick -size 2000x2000 xc:black -clahe 0x0 null:

<img width="1069" height="70" alt="image" src="https://github.com/user-attachments/assets/ecbab79c-a3c2-4e8c-96c9-8e2aa8f0d2b2" />

→ Significant memory consumption and evidence of memory region corruption.

./magick -size 4000x4000 xc:black -clahe 0x0 null:

<img width="776" height="49" alt="image" src="https://github.com/user-attachments/assets/63a7cec5-616b-4aa5-87f3-a546a87e6625" />

→ Much larger memory usage; process appears to be aggressively consuming cache and address space.

./magick -size 8000x8000 xc:black -clahe 0x0 null:

<img width="748" height="46" alt="image" src="https://github.com/user-attachments/assets/48b3aac8-98b3-4fbb-a5ca-4e7936bca44b" />

→ Memory usage escalates further and begins exhausting available cache. If left running, the process is likely to crash (DoS) after sustained allocation attempts.

Division-by-zero

Environment: ASan/UBSan-enabled build.

export UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
export ASAN_OPTIONS=abort_on_error=1:allocator_may_return_null=1:detect_leaks=0

Command

./magick -size 16x2 gradient: -type TrueColor -depth 8 -clahe 0x0! null:

Output

<img width="1915" height="818" alt="image" src="https://github.com/user-attachments/assets/cfe44432-b429-49e4-8673-2ed55ba9a961" />

Notes: Without sanitizers, the process may terminate with just Aborted (still DoS).


Impact

  • Primary: Denial-of-Service — crash or sustained resource exhaustion (memory/cache thrash) when processing crafted parameters or small images via CLI or API. Attackers can trivially trigger via clahe 0x0! or by uploading very small images to services using ImageMagick.
  • Secondary (theoretical): OOB memory accesses and memory corruption could potentially be combined with other vulnerabilities to achieve more severe outcomes; however, no reliable code execution was demonstrated from these PoCs alone.

Suggested concrete patch snippets

Apply in CLAHEImage() after tile_info is computed but before any division/modulus/pointer arithmetic:

if (exact_tiles_requested && (tile_info.width == 0 || tile_info.height == 0)) {
  ThrowMagickException(exception, GetMagickModule(), OptionError,
                       "CLAHEInvalidTile", "%lux%lu",
                       (unsigned long) tile_info.width,
                       (unsigned long) tile_info.height);
  return (Image *) NULL;
}

if (!exact_tiles_requested) {
  tile_info.width  = (tile_info.width  == 0) ? MagickMax((size_t)1, image->columns >> 3) : tile_info.width;
  tile_info.height = (tile_info.height == 0) ? MagickMax((size_t)1, image->rows    >> 3) : tile_info.height;
}

if (tile_info.width == 0 || tile_info.height == 0) {
  ThrowMagickException(exception, GetMagickModule(), OptionError,
                       "CLAHEInvalidTile", "%lux%lu",
                       (unsigned long) tile_info.width,
                       (unsigned long) tile_info.height);
  return (Image *) NULL;
}

ssize_t tile_h_minus1 = (ssize_t)tile_info.height - 1;
if (tile_h_minus1 < 0) {
  ThrowMagickException(exception, GetMagickModule(), OptionError,
                       "CLAHEInvalidTile", "%lux%lu",
                       (unsigned long) tile_info.width,
                       (unsigned long) tile_info.height);
  return (Image *) NULL;
}
p += (ptrdiff_t) clahe_info->width * tile_h_minus1;

Notes about exact_tiles_requested: if the CLI/Wand parser already exposes whether ! was present, use it. If not, add a parse-time flag so CLAHEImage can know whether 0 is literal or auto.


Credit

Team Whys

Bug Hunting Master Program, HSpace/Findthegap

Youngmin Kim [email protected]

Woojin Park

@jin-156 [email protected]

Youngin Won

@amethyst0225 [email protected]

Siyeon Han

@hanbunny [email protected]

Shinyoung Won

@yosiimich [email protected]

Affected Packages

12 total
EcosystemPackageVulnerable rangeFix
.NETNuGetMagick.NET-Q16-x64all versionsNo fix
.NETNuGetMagick.NET-Q8-x64all versionsNo fix
.NETNuGetMagick.NET-Q16-HDRI-x64all versionsNo fix
.NETNuGetMagick.NET-Q8-OpenMP-x64all versionsNo fix
.NETNuGetMagick.NET-Q16-HDRI-OpenMP-x64all versionsNo fix
.NETNuGetMagick.NET-Q16-OpenMP-x64all versionsNo fix

Affected Products

1 product · 1 configurations
Application
imagemagickimagemagick
< 7.1.2-8
range

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for Magick.NET-Q16-x64, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Remediation status

    The records we use list no patched version of Magick.NET-Q16-x64 for CVE-2025-62594. Check the maintainer's advisory, and where your build allows, override or pin the dependency away from the vulnerable range.

  3. Mitigate without a patch

    Stop feeding it untrusted input: reject or quarantine files and payloads from unverified sources until you can upgrade, restrict accepted formats to the ones you actually need, and run the parsing or decoding step in a least-privileged sandbox or short-lived worker so a crash or corrupted read cannot reach the rest of the process.

Fixing This On Your OS

If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.

Red HatModerate

This vulnerability is rated as Moderate because its primary impact is limited to denial-of-service (DoS) rather than data compromise or code execution. Although the flaw involves unsafe pointer arithmetic and division-by-zero conditions, the exploitability is constrained — it requires user interaction or crafted input…

Workaround published by Red Hat
No mitigation is currently available that meets Red Hat Product Security’s standards for usability, deployment, applicability, or stability. The risk can be reduced by disabling or restricting the use of the CLAHE feature in environments that process untrusted images. Administrators can update policy.xml or application logic to block the -clahe option, reject inputs specifying zero or very small tile dimensions, and enforce strict memory and CPU limits on ImageMagick processes.
Source: Red Hat security advisory for CVE-2025-62594 (CC BY 4.0)

Frequently Asked Questions

## Summary A single root cause in the CLAHE implementation — tile width/height becoming zero — produces two distinct but related unsafe behaviors. Vulnerabilities exists in the `CLAHEImage()` function of ImageMagick’s `MagickCore/enhance.c`. 1. Unsigned integer underflow → out-of-bounds pointer arithmetic (OOB): when `tile_info.height == 0`, the expression `tile_info.height - 1` (unsigned) wraps to a very large value; using that value in pointer arithmetic yields a huge offset and OOB memory access (leading to memory corruption, SIGSEGV, or resource exhaustion). 2. **Division/modulus by zero
O3 Security · Impact-Aware SCA

Is CVE-2025-62594 in your dependencies?

Find it across NuGet, including transitive dependencies.

CVE-2025-62594: Magick.NET-Q16-x64 DoS (Medium 4.7)