Feb 24, 2026·6 min read·57 visits
A memory leak in ImageMagick's MSL component allows attackers to crash servers via DoS. By sending requests that trigger the `WriteMSLImage` function, the server allocates memory for a cloned image but never frees it. Fix involves patching to 7.1.2-15+ or disabling MSL in policy.xml.
ImageMagick, the ubiquitous Swiss Army knife of image processing, has stumbled again—not with a high-profile Remote Code Execution (RCE) this time, but with a silent killer: a memory leak in the Magick Scripting Language (MSL) encoder. CVE-2026-25638 allows unauthenticated attackers to exhaust server memory by triggering the `WriteMSLImage` function, leading to a Denial of Service (DoS). While less glamorous than shell access, this vulnerability highlights the dangers of legacy components and improper resource management in C.
ImageMagick is the software equivalent of a hoarder's garage. It keeps everything. Did you know ImageMagick has its own XML-based scripting language called MSL (Magick Scripting Language)? Neither did half the developers using it. But in the world of vulnerability research, obscure features are where the bodies are buried.
CVE-2026-25638 targets this specific corner of the codebase: the coders/msl.c module. This component is responsible for interpreting and writing MSL scripts. While modern web applications typically interact with ImageMagick via libraries or CLI wrappers to convert JPEGs to PNGs, the internal machinery still loads these obscure coders if not explicitly forbidden.
This vulnerability isn't the flashy "ImageTragick" RCE that keeps CISOs up at night. It's something more insidious. It's a resource exhaustion bug—a memory leak. It’s the equivalent of opening a new tab in Chrome every time a user visits your site, but never closing it. Eventually, the machine stops responding. For high-throughput image processing pipelines (like those used by social media platforms or e-commerce sites), this is a production-halting nightmare waiting to happen.
To understand this bug, we have to look at how ImageMagick handles image transformations internally. When the MSL writer is invoked, it needs to perform operations on an image without destroying the original data immediately. To do this, it creates a clone.
In coders/msl.c, the function WriteMSLImage is called. Its job is to take the current image state and process it according to the MSL script provided. The developers correctly identified that they shouldn't modify the input image directly in case the operation failed or needed to be non-destructive initially. So, they called CloneImage.
Here is where the logic falls apart. In C, there is no garbage collector to sweep up after you. If you malloc (or in this case, CloneImage), you must free (or DestroyImageList). The vulnerable code allocates a potentially large structure on the heap to hold the msl_image, passes it to the processing function, and then... just walks away. The function returns the status code, leaving the cloned image stranded in memory. It is an orphan object, occupying RAM, with no pointer left to free it.
Let's look at the diff. It is painfully simple, which is characteristic of the most annoying bugs to debug. The fix introduced in commit 1e88fca11c7b8517100d518bc99bd8c474f02f88 adds exactly one line of cleanup code.
Here is the vulnerable flow in coders/msl.c:
/* Vulnerable Code */
static MagickBooleanType WriteMSLImage(const ImageInfo *image_info, Image *image,
ExceptionInfo *exception)
{
Image *msl_image;
MagickBooleanType status;
/* ... setup code ... */
/* 1. ALLOCATION: Create a deep copy of the image */
msl_image = CloneImage(image, 0, 0, MagickTrue, exception);
/* 2. USE: Process the script using the clone */
status = ProcessMSLScript(image_info, &msl_image, exception);
/* 3. RETURN: The function exits, leaking msl_image! */
return(status);
}The fix is the digital equivalent of remembering to turn off the stove:
msl_image=CloneImage(image,0,0,MagickTrue,exception);
status=ProcessMSLScript(image_info,&msl_image,exception);
+ msl_image=DestroyImageList(msl_image);
return(status);Without that DestroyImageList call, every single request that hits this code path leaks the size of the image structure plus its pixel cache. If you send a 4K image to be processed by MSL, you aren't just leaking a few bytes; you could be leaking dozens of megabytes per request.
How do we weaponize a memory leak? We don't need complex shellcode or ROP chains. We just need persistence and volume. The goal is the OOM (Out of Memory) Killer.
The attacker needs to force the server to invoke the MSL coder. If the application allows users to upload files and automatically detects the format based on magic bytes or file extension, the attacker can upload a file named payload.msl or simply an XML file with MSL headers.
/api/convert or /profile/upload that uses ImageMagick.<?xml version="1.0" encoding="UTF-8"?>
<image>
<read filename="image.jpg" />
<resize geometry="100x100" />
<write filename="output.png" />
</image>WriteMSLImage is called 50 times a second. Each call clones image.jpg. The heap grows. The garbage collector (if the app wrapper has one) can't help because the leak is inside the C library, outside the managed runtime's view.magick worker. The service goes dark.There are two ways to fix this. One is surgical, the other is architectural.
Obviously, update ImageMagick. The fix is available in versions 7.1.2-15 and 6.9.13-40. This patches the specific leak in coders/msl.c. If you are compiling from source, ensure you have commit 1e88fca applied.
This is the "Hacker's Choice" for defense. Why does your web server even know how to process MSL scripts? The principle of least privilege applies to code, too. ImageMagick's policy.xml is a powerful firewall for format parsers.
You should explicitly disable the MSL coder (and any others you don't use, like MVG, XPS, or PDF) to reduce your attack surface.
<policymap>
<!-- Disable MSL completely -->
<policy domain="coder" rights="none" pattern="MSL" />
<!-- While you're at it, disable these usually dangerous ones too -->
<policy domain="coder" rights="none" pattern="MVG" />
<policy domain="coder" rights="none" pattern="HTTPS" />
</policymap>By adding this policy, even if the binary is vulnerable, the exploit fails at step 1 because ImageMagick will refuse to load the MSL module entirely.
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 | >= 7.0.0, < 7.1.2-15 | 7.1.2-15 |
ImageMagick ImageMagick | < 6.9.13-40 | 6.9.13-40 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-401 (Missing Release of Memory) |
| CVSS v3.1 | 5.3 (Medium) |
| Attack Vector | Network (AV:N) |
| Impact | Denial of Service (Availability) |
| Component | coders/msl.c (WriteMSLImage) |
| Exploit Maturity | Proof of Concept |
Missing Release of Memory after Effective Lifetime
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.
CVE-2026-48596 is an Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Request/Response Splitting, CWE-113) in the Elixir Tesla HTTP client. The flaw resides in how multipart content-type parameters are joined and serialized, enabling attackers to inject arbitrary headers or split HTTP requests when applications pass untrusted inputs to the parameters of multipart uploads.
An improper handling of highly compressed data (decompression bomb) vulnerability exists in the Elixir Tesla HTTP client when utilizing response decompression middlewares. By serving highly compressed responses or stacked content-encoding headers, a malicious server can cause arbitrary heap exhaustion, leading to a denial of service (DoS) crash in the BEAM virtual machine.
A high-severity security vulnerability in Elixir's Tesla HTTP client library (CVE-2026-48595) allows unauthenticated remote attackers to harvest sensitive credentials, including Authorization headers and cookies. The flaw resides in the 'Tesla.Middleware.FollowRedirects' component, which performs case-sensitive lookups when stripping credentials during cross-origin redirects. Because HTTP headers are case-insensitive by RFC specifications, standard canonical casing (e.g., 'Authorization') bypasses the lowercase-only blocklist, leaking tokens to untrusted external redirect destinations.