Mar 27, 2026·6 min read·30 visits
A memory leak in ImageMagick's META reader allows attackers to cause memory exhaustion and Denial of Service (DoS) via crafted image files that trigger an unhandled error path during JPEG embedding.
ImageMagick and its downstream wrapper libraries, including Magick.NET, contain a memory leak vulnerability in the META reader component. The flaw, identified as CWE-401, resides in the APP1JPEG input and error handling paths within `coders/meta.c`. When processing malformed image profiles, the application fails to release allocated memory structures, allowing an attacker to trigger memory exhaustion and subsequent Denial of Service (DoS) by submitting specially crafted files.
ImageMagick relies on various coder modules to parse and process different image formats. The META reader component, implemented in coders/meta.c, is responsible for handling metadata embedded within images. Downstream libraries such as Magick.NET utilize these core libraries to expose image manipulation capabilities to higher-level application frameworks.
The vulnerability is categorized as CWE-401: Missing Release of Memory after Effective Lifetime. It is localized to the ReadMETAImage function, which processes image profiles during the APP1JPEG parsing sequence. When specific conditions are met, memory allocated for profile data and image blobs is orphaned rather than properly returned to the memory manager.
Although the severity is rated as Low, the vulnerability exposes long-running applications to Denial of Service (DoS) risks. Web applications, background processing queues, and APIs that accept untrusted user uploads are particularly susceptible. Continuous processing of malformed inputs will predictably exhaust available process memory, leading to application crashes or system-level instability.
The root cause stems from incomplete memory deallocation procedures within two distinct execution paths in ReadMETAImage. The first issue involves the lifecycle of the StringInfo profile object. The application extracts profile data and attaches it to the iptc blob using AttachBlob. However, the code subsequently fails to invoke DestroyStringInfo(profile).
Without this explicit destruction, the header structure of the StringInfo object remains allocated in memory. The pointer to this structure falls out of scope when the function returns, permanently orphaning the memory segment. This constitutes a persistent leak that triggers every time this specific metadata extraction path is executed.
The second, more severe leak occurs within the error handling logic for the jpeg_embed function. If jpeg_embed encounters invalid embedded JPEG data or resource constraints, it returns 0 to indicate failure. The routine intercepts this failure and calls ThrowReaderException to abort the operation.
Prior to aborting, the application calls DestroyImage(buff) to clean up the image metadata structure. However, it neglects to detach and relinquish the underlying image data blob (buff->blob). The metadata pointer is destroyed, severing the application's reference to the payload, while the actual blob remains stranded in heap memory.
The remediation was introduced in commit bee248ee853a686a969fae9cfb1e02dd5aae245b by the ImageMagick maintainers. The patch modifies coders/meta.c to enforce explicit memory cleanup in both identified leak scenarios.
--- a/coders/meta.c
+++ b/coders/meta.c
@@ -1333,12 +1333,17 @@ static Image *ReadMETAImage(const ImageInfo *image_info,
}
AttachBlob(iptc->blob,GetStringInfoDatum(profile),
GetStringInfoLength(profile));
+ profile->datum=(unsigned char *) NULL;
+ profile->length=0;
+ profile=DestroyStringInfo(profile);
result=jpeg_embed(image,buff,iptc);
blob=(unsigned char *) DetachBlob(iptc->blob);
blob=(unsigned char *) RelinquishMagickMemory(blob);
iptc=DestroyImage(iptc);
if (result == 0)
{
+ blob=(unsigned char *) DetachBlob(buff->blob);
+ blob=(unsigned char *) RelinquishMagickMemory(blob);
buff=DestroyImage(buff);
ThrowReaderException(CoderError,"JPEGEmbeddingFailed");
}The first block of additions addresses the StringInfo leak. After attaching the profile data to the blob, the patch nullifies the datum pointer and resets the length to zero. It then correctly passes the profile to DestroyStringInfo, safely deallocating the structure header and preventing the initial memory leak.
The second block addresses the error path leak. When result == 0, the patched code now explicitly extracts the blob pointer via DetachBlob(buff->blob). It then routes this pointer through RelinquishMagickMemory(blob) before invoking DestroyImage(buff). This guarantees that the bulky image payload is freed before the metadata structure tracking it is destroyed.
To exploit this vulnerability, an attacker must have the ability to supply a crafted image file to an application utilizing the vulnerable ImageMagick components. The payload file must include specific metadata profiles designed to force the META reader to route execution into the APP1JPEG parsing branch.
The attacker constructs the embedded JPEG data to be intentionally malformed or incompatible with the expected embedding constraints. When ReadMETAImage invokes jpeg_embed on this data, the routine predictably fails and returns 0. This forces the execution flow into the flawed error handling block, triggering the memory leak.
A single execution of this attack payload leaks a finite amount of heap memory corresponding to the size of the embedded blob and the profile structures. Consequently, exploitation requires a volumetric approach. The attacker must continuously submit the malformed image to the target application to incrementally consume available RAM.
The attack is highly viable against asynchronous processing queues and stateless API endpoints that do not enforce strict process recycling. The memory footprint of the host process will steadily grow until it triggers an Out-Of-Memory (OOM) condition, resulting in process termination.
The primary security consequence of this vulnerability is a targeted Denial of Service (DoS) via resource exhaustion. The vulnerability does not permit memory corruption, out-of-bounds writing, or arbitrary code execution. The impact is strictly limited to availability.
In containerized environments, the unchecked memory growth will eventually breach the configured limits (e.g., Docker memory constraints or Kubernetes resource quotas). When this threshold is exceeded, the container orchestration platform will forcefully kill the pod or container, disrupting active processing tasks and temporarily degrading service availability.
For managed wrappers such as Magick.NET, the impact is particularly acute. Because the leak occurs within native unmanaged code, the .NET Common Language Runtime (CLR) garbage collector is entirely unaware of the orphaned memory. The application's managed memory footprint will appear stable, while the process working set expands uncontrollably at the OS level, evading standard application-level memory monitoring tools.
The vulnerability is permanently resolved by applying the vendor patch. Organizations using direct installations of ImageMagick must update their binaries or recompile from source using commit bee248ee853a686a969fae9cfb1e02dd5aae245b or any subsequent stable release.
Development teams utilizing the Magick.NET ecosystem must update their project dependencies. Ensure that all variants, including Magick.NET-Q16-AnyCPU and Magick.NET-Q16-HDRI-OpenMP-arm64, are explicitly upgraded to version 14.11.1 via the NuGet package manager.
If immediate patching is technically infeasible, operational mitigations should be deployed. Implement aggressive cgroup memory limits on the processes handling image processing. Configure the application architecture to routinely recycle background worker processes after a set number of tasks to flush unmanaged memory accumulations.
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
ImageMagick ImageMagick Studio LLC | < bee248ee853a686a969fae9cfb1e02dd5aae245b | bee248ee853a686a969fae9cfb1e02dd5aae245b |
Magick.NET-Q16-AnyCPU Dirk Lemstra | < 14.11.1 | 14.11.1 |
Magick.NET-Q16-HDRI-OpenMP-arm64 Dirk Lemstra | < 14.11.1 | 14.11.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-401 |
| Attack Vector | Local / Network (File Parsing) |
| Impact | Denial of Service (Memory Exhaustion) |
| Exploit Status | Proof-of-Concept |
| CVSS Score | 3.3 |
| Remediation | Patch Available |
Missing Release of Memory after Effective Lifetime
CVE-2026-48708 details a critical concurrency synchronization flaw in OliveTin versions < 3000.13.0. A shared package-level text/template.Template instance is accessed concurrently across multiple goroutines without proper synchronization. When concurrent request processing occurs, a race condition causes Go runtime panics or command contamination across separate sessions, enabling denial of service or execution of contaminated commands.
A missing authorization vulnerability in the OliveTin system allows unauthenticated remote actors to query the ValidateArgumentType RPC endpoint. By exploiting this flaw, attackers can execute systematic brute-force and side-channel validation attacks to enumerate active action binding IDs, parameter structures, and operational metadata, bypassing configured guest authentication barriers.
An observable timing discrepancy vulnerability (CWE-208) in Filament's administrative login page allows unauthenticated remote attackers to determine the existence of registered email addresses. This timing side-channel arises from short-circuiting logic that skips expensive password hashing checks when a queried email address is not found in the database. Attackers can execute statistical timing attacks to map active administrator accounts, facilitating subsequent targeted brute-force or credential-stuffing campaigns.
Filament's ImageColumn (used in tables) and ImageEntry (used in infolists) components render database values inside HTML attributes without validation or sanitization. This allows an attacker to inject arbitrary HTML attributes, leading to Stored Cross-Site Scripting (XSS).
The Netty incubator codec for Oblivious HTTP (OHTTP) fails to verify that a cryptographically signed final chunk is received before the outer HTTP body terminates. This missing validation allows an on-path adversary to truncate chunked-OHTTP messages cleanly at a non-final chunk boundary, leading to undetected data truncation and compromising message integrity. The vulnerability affects multiple versions of the maven package io.netty.incubator:netty-incubator-codec-ohttp prior to 0.0.22.Final.
Prior to version 4.1.4, phpMyFAQ used the cryptographically broken SHA-1 algorithm to hash custom attachment encryption keys stored in the database. Attackers with database access can recover these plaintext keys through offline brute-force attacks and subsequently decrypt sensitive file attachments.