Feb 24, 2026·5 min read·36 visits
ImageMagick's MSL component fails to validate image pointers before use in the <map> tag processing logic. This Use-After-Free condition allows attackers to crash the application (DoS) via crafted MSL scripts. Fixed in versions 7.1.2-15 and 6.9.13-40.
A Use-After-Free (UAF) vulnerability exists in the Magick Scripting Language (MSL) interpreter of ImageMagick. By feeding a malformed XML-based script to the engine, an attacker can trigger memory corruption when the interpreter mishandles the lifecycle of image objects during a map operation. While primarily a Denial of Service (DoS) vector, the unstable nature of UAF bugs in complex parsers always warrants immediate attention.
ImageMagick is the 'Swiss Army Knife' of image processing. It’s everywhere—PHP modules, Python scripts, command-line tools, and web servers. But hidden deep within its massive codebase lies the Magick Scripting Language (MSL). If you haven't heard of it, you're not alone. It's an XML-based scripting capability that allows users to define complex image manipulation pipelines in a declarative format.
Here is the problem: Parsing XML to control memory-unsafe C code is like juggling chainsaws while blindfolded. It requires absolute precision in object lifecycle management.
CVE-2026-26983 is a classic memory corruption bug residing in this obscure interpreter. It turns out that when you tell the MSL engine to map images using the <map> tag, it doesn't quite check if the image map actually exists—or if it has already been sent to the great bitbucket in the sky. This oversight leads to a Use-After-Free (UAF) condition, crashing the process and potentially opening the door for more creative heap manipulation.
The vulnerability lives in coders/msl.c, specifically within the MSLStartElement function. This massive state machine parses the XML tags provided in an MSL script. When the parser encounters a <map> tag, it attempts to perform a color remapping operation.
To do this, it utilizes a pointer named affinity_image. In a well-behaved world, affinity_image points to a valid Image structure loaded into memory. However, the logic handling the <map> element assumed that if the code reached that block, the pointer was valid and ready for action.
It failed to account for scenarios where the image might have been destroyed by a previous operation or never properly initialized due to a malformed script structure. The code blindly passes this pointer to RemapImages and subsequently calls DestroyImage on it. If that pointer refers to freed memory, we trigger the Use-After-Free. It's the digital equivalent of trying to sit on a chair that someone just pulled out from under you.
Let's look at the patch, which is often the best documentation for a vulnerability. The fix was applied in commit 7cfae4da24a995fb05386d77364ff404a7cca7bc. It’s a textbook example of defensive programming (or the lack thereof in the vulnerable version).
The Vulnerable Code:
Note how RemapImages and DestroyImage are called without hesitation.
/* coders/msl.c - Vulnerable Logic */
(void) RemapImages(quantize_info, msl_info->image[n], affinity_image, exception);
quantize_info=DestroyQuantizeInfo(quantize_info);
affinity_image=DestroyImage(affinity_image);The Fixed Code:
The fix introduces a sanity check. We explicitly verify that affinity_image is not NULL before touching it. It effectively says, "Do we actually have an image here?"
/* coders/msl.c - Patched Logic */
if (affinity_image != (Image *) NULL)
{
(void) RemapImages(quantize_info, msl_info->image[n], affinity_image, exception);
affinity_image=DestroyImage(affinity_image);
}
quantize_info=DestroyQuantizeInfo(quantize_info);This simple if statement prevents the interpreter from dereferencing a NULL or invalid pointer, effectively neutralizing the crash.
Exploiting this is relatively straightforward if you can feed an MSL file to an ImageMagick instance. The goal is to construct an MSL script that defines a <map> operation without a valid mapping image context, or in a sequence that invalidates the image before the map triggers.
An attacker would craft a payload looking something like this:
<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="image:test.jpg" />
<!-- The trigger: invoking map without proper setup -->
<map />
</image>When magick processes this via the MSL coder (often invoked via msl:payload.xml), the parser hits the <map> tag. The internal affinity_image variable is likely uninitialized or stale from a previous state. The application attempts to read from this memory address to perform the remap.
Result: Segmentation Fault (SIGSEGV). The process dies immediately. In a web server context where ImageMagick is spawned to process uploads, this can lead to resource exhaustion if the attacker floods the server with these requests, or simply disrupt the service for legitimate users.
You might look at the CVSS score of 5.3 and shrug. "It's just a DoS," you say. "I'll fix it next quarter."
Don't be that person.
While this vulnerability is currently classified as a Denial of Service, Use-After-Free bugs are notoriously finicky. With precise heap Feng Shui (manipulating the memory layout), a skilled attacker might be able to replace the freed affinity_image object with a fake object containing malicious function pointers. If they succeed, that "harmless crash" turns into Remote Code Execution (RCE).
Even without RCE, if your application relies on ImageMagick for automated processing (e.g., generating thumbnails, converting formats), a single malicious file can bring your pipeline to a halt. If you are processing untrusted input—which ImageMagick almost always is—you are vulnerable.
The remediation path is standard but urgent. You have two primary options:
1. The Patch Upgrade to ImageMagick 7.1.2-15 or 6.9.13-40. These versions include the null-check logic that prevents the UAF. This is the only way to retain MSL functionality safely.
2. The Policy Hardening (Recommended)
Ask yourself: Do you actually need MSL? Does your web app really need to parse XML-based image manipulation scripts? Probably not. ImageMagick's policy.xml is a powerful tool to reduce your attack surface.
Add the following line to your policy.xml to globally disable the MSL coder:
<policy domain="coder" rights="none" pattern="MSL" />This is a 'nuclear option' for the feature, but it renders the vulnerability unexploitable regardless of the installed version. In security, turning off features you don't use is always the best policy.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
ImageMagick ImageMagick | < 6.9.13-40 | 6.9.13-40 |
ImageMagick ImageMagick | >= 7.0.0, < 7.1.2-15 | 7.1.2-15 |
| Attribute | Detail |
|---|---|
| Attack Vector | Network (via MSL script) |
| CVSS v3.1 | 5.3 (Medium) |
| CWE ID | CWE-416 (Use-After-Free) |
| Impact | Denial of Service (Crash) |
| Exploit Status | PoC Available (Internal) |
| Component | MSL Interpreter (coders/msl.c) |
The product reuses or references a memory location after that location has been freed. This can cause the application to crash, use unexpected values, or execute code.
A high-severity denial-of-service vulnerability in @libp2p/gossipsub prior to version 16.0.0 allows unauthenticated remote attackers to trigger event loop starvation and complete node freeze by exploiting unbounded protobuf decoding limits and nested synchronous array iteration loops.
CVE-2026-49858 is a vulnerability in API Platform Core's JSON:API and HAL item normalizers where conditionally secured attributes are cached globally in memory. When deployed in long-running PHP execution environments such as FrankenPHP worker mode, Swoole, or RoadRunner, this persistent caching bypasses property-level security constraints, allowing unprivileged users to access sensitive, unauthorized fields cached during privileged requests.
CVE-2026-5078 is a log injection vulnerability in Morgan, the widely deployed Node.js HTTP request logging middleware. The vulnerability arises because the ':remote-user' logging token decodes and outputs basic authentication usernames containing control characters, such as Carriage Return (CR) and Line Feed (LF), without sanitization. An unauthenticated attacker can bypass native HTTP header parsers by Base64-encoding CRLF sequences in the Authorization header. When Morgan logs the request, these control characters force newlines in the log stream, enabling log forging, SIEM evasion, and system activity spoofing.
CVE-2026-48861 is a client-side HTTP request-line CRLF (Carriage Return Line Feed) injection vulnerability in the popular Elixir HTTP client library, Mint. The vulnerability permits HTTP Request Splitting and HTTP Request Smuggling when an application forwards untrusted, attacker-controlled inputs to Mint's HTTP client requests as either the HTTP request method or target. By embedding CRLF characters within these parameters, an attacker can terminate the request line prematurely, inject malicious headers, or pipeline entirely independent requests. These smuggled requests are then processed by upstream or downstream proxy servers as separate HTTP queries on the same TCP connection. While Mint version 1.7.0 introduced target validation to secure the request target, the HTTP request method parameter remained completely unvalidated. This flaw allows attackers to bypass routing filters, access restricted internal APIs, or poison HTTP caches under default configurations.
An Inconsistent Interpretation of HTTP Requests (HTTP Request/Response Smuggling) vulnerability in the Elixir Mint HTTP client allows attacker-controlled HTTP/1 servers to desynchronize response framing on shared connections due to over-lenient parsing of sign-prefixed Content-Length headers.
An allocation of resources without limits or throttling vulnerability in Elixir Mint allows an attacker-controlled HTTP/2 server to exhaust memory in a Mint client. The vulnerability is exploited by sending a HEADERS frame without the END_HEADERS flag followed by an infinite stream of CONTINUATION frames. Because the client lacks limits on the incoming header-block accumulator, the client continuously consumes memory until an out-of-memory crash occurs.