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
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.
CVE-2026-48597 is a high-severity Denial of Service (DoS) vulnerability in the Elixir HTTP client library Tesla (specifically involving the Mint adapter) that allows an unauthenticated remote attacker to cause an unrecoverable crash of the Erlang Virtual Machine (BEAM). The flaw arises from the dynamic conversion of untrusted URL schemes into Erlang atoms without validation, leading to global atom table exhaustion.
An Improper Encoding or Escaping of Output vulnerability (CWE-116) in elixir-tesla allowed unauthenticated remote code execution or request smuggling via unescaped Content-Disposition parameters in multipart form-data requests.
CVE-2026-49851 is a high-severity algorithmic complexity vulnerability in the Mistune Markdown parser. Under specific conditions involving dense, unmatched nesting of opening square brackets, the parser fallback loops degrade from linear execution time to a worst-case quadratic complexity. This allows unauthenticated remote attackers to trigger complete CPU exhaustion and subsequent Denial of Service with a highly compact payload.
An allocation of resources without limits or throttling vulnerability in the Elixir Mint HTTP client library allows malicious HTTP/2 servers to trigger memory exhaustion and application denial of service. The flaw exists because Mint fails to validate server-push concurrency limits during the receipt of PUSH_PROMISE frames, deferring validation to the HEADERS phase. This allows a server to reserve an unlimited number of streams in the client's memory map.