CVE-2026-23874 is a medium severity vulnerability with a CVSS score of 5.5. No known exploits currently, and patches are available.
Very low probability of exploitation
EPSS predicts the probability of exploitation in the next 30 days based on real-world threat data, complementing CVSS severity scores with actual risk assessment.
Stack overflow via infinite recursion in MSL (Magick Scripting Language) <write> command when writing to MSL format.
magick MSL:recursive.msl out.png
python3 infra/helper.py build_fuzzers imagemagick
python3 infra/helper.py reproduce imagemagick msl_fuzzer recursive.msl
Or run the fuzzer directly:
./msl_fuzzer recursive.msl
ImageMagick should handle recursive MSL references gracefully by detecting the loop and returning an error.
Stack overflow causes process crash:
AddressSanitizer:DEADLYSIGNAL
==PID==ERROR: AddressSanitizer: stack-overflow
#0 MSLStartElement /src/imagemagick/coders/msl.c:7045
#1 xmlParseStartTag /src/libxml2/parser.c
#2 xmlParseChunk /src/libxml2/parser.c:11273
#3 ProcessMSLScript /src/imagemagick/coders/msl.c:7405
#4 WriteMSLImage /src/imagemagick/coders/msl.c:7867
#5 WriteImage /src/imagemagick/MagickCore/constitute.c:1346
#6 MSLStartElement /src/imagemagick/coders/msl.c:7045
... (infinite recursion, 287+ frames)
In coders/msl.c, the <write> command handler in MSLStartElement() (line ~7045) calls WriteImage(). When the output filename specifies MSL format (msl:filename), WriteMSLImage() is called, which parses the MSL file again via ProcessMSLScript().
If the MSL file references itself (directly or indirectly), this creates an infinite recursion loop:
MSLStartElement() → WriteImage() → WriteMSLImage() → ProcessMSLScript()
→ xmlParseChunk() → MSLStartElement() → ... (infinite loop)
The <read> command can also trigger recursion:
Indirect recursion is also possible (a.msl → b.msl → a.msl).
This issue was discovered using a custom MSL fuzzer:
#include <cstdint>
#include <Magick++/Blob.h>
#include <Magick++/Image.h>
#include "utils.cc"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
if (IsInvalidSize(Size))
return(0);
try
{
const Magick::Blob blob(Data, Size);
Magick::Image image;
image.magick("MSL");
image.fileName("MSL:");
image.read(blob);
}
catch (Magick::Exception)
{
}
return(0);
}
This issue was found by Team FuzzingBrain @ Texas A&M University
Please cite this page when referencing data from Strobes VI. Proper attribution helps support our vulnerability intelligence research.