{"id":"CVE-2026-23874","aliases":["GHSA-9vj4-wc7r-p844"],"url":"https://o3.security/vulnerability/CVE-2026-23874","summary":"ImageMagick's MSL: Stack overflow via infinite recursion in ProcessMSLScript","details":"## Summary\n\nStack overflow via infinite recursion in MSL (Magick Scripting Language) `<write>` command when writing to MSL format.\n\n## Version\n\n- ImageMagick 7.x (tested on current main branch)\n- Commit: HEAD\n- Requires: libxml2 support (for MSL parsing)\n\n## Steps to Reproduce\n\n### Method 1: Using ImageMagick directly\n\n```bash\nmagick MSL:recursive.msl out.png\n```\n\n### Method 2: Using OSS-Fuzz reproduce\n\n```bash\npython3 infra/helper.py build_fuzzers imagemagick\npython3 infra/helper.py reproduce imagemagick msl_fuzzer recursive.msl\n```\n\nOr run the fuzzer directly:\n```bash\n./msl_fuzzer recursive.msl\n```\n\n## Expected Behavior\n\nImageMagick should handle recursive MSL references gracefully by detecting the loop and returning an error.\n\n## Actual Behavior\n\nStack overflow causes process crash:\n\n```\nAddressSanitizer:DEADLYSIGNAL\n==PID==ERROR: AddressSanitizer: stack-overflow\n    #0 MSLStartElement /src/imagemagick/coders/msl.c:7045\n    #1 xmlParseStartTag /src/libxml2/parser.c\n    #2 xmlParseChunk /src/libxml2/parser.c:11273\n    #3 ProcessMSLScript /src/imagemagick/coders/msl.c:7405\n    #4 WriteMSLImage /src/imagemagick/coders/msl.c:7867\n    #5 WriteImage /src/imagemagick/MagickCore/constitute.c:1346\n    #6 MSLStartElement /src/imagemagick/coders/msl.c:7045\n    ... (infinite recursion, 287+ frames)\n```\n\n## Root Cause Analysis\n\nIn `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()`.\n\nIf the MSL file references itself (directly or indirectly), this creates an infinite recursion loop:\n\n```\nMSLStartElement() → WriteImage() → WriteMSLImage() → ProcessMSLScript()\n    → xmlParseChunk() → MSLStartElement() → ... (infinite loop)\n```\n\n## Impact\n\n- **DoS**: Guaranteed crash via stack exhaustion\n- **Affected**: Any application using ImageMagick to process user-supplied MSL files\n\n## Additional Trigger Paths\n\nThe `<read>` command can also trigger recursion:\n\nIndirect recursion is also possible (a.msl → b.msl → a.msl).\n\n## Fuzzer\n\nThis issue was discovered using a custom MSL fuzzer:\n\n```cpp\n#include <cstdint>\n#include <Magick++/Blob.h>\n#include <Magick++/Image.h>\n#include \"utils.cc\"\n\nextern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)\n{\n  if (IsInvalidSize(Size))\n    return(0);\n  try\n  {\n    const Magick::Blob blob(Data, Size);\n    Magick::Image image;\n    image.magick(\"MSL\");\n    image.fileName(\"MSL:\");\n    image.read(blob);\n  }\n  catch (Magick::Exception)\n  {\n  }\n  return(0);\n}\n```\n\nThis issue was found by Team FuzzingBrain @ Texas A&M University","published":"2026-01-20T00:52:52.916Z","modified":"2026-08-12T03:51:17.155017222Z","cvss":{"score":5.5,"severity":"MEDIUM","vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H"},"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"NuGet","name":"Magick.NET-Q8-x64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q8-arm64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q8-x86","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q8-OpenMP-x64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q8-OpenMP-arm64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-x64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-arm64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-x86","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-OpenMP-x64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-OpenMP-arm64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-HDRI-x64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-HDRI-arm64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-HDRI-x86","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-HDRI-OpenMP-x64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-HDRI-OpenMP-arm64","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q8-AnyCPU","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-AnyCPU","fixedVersion":"14.10.2"},{"ecosystem":"NuGet","name":"Magick.NET-Q16-HDRI-AnyCPU","fixedVersion":"14.10.2"}],"fix":null,"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/23xxx/CVE-2026-23874.json"},{"type":"ADVISORY","url":"https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-9vj4-wc7r-p844"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-23874"},{"type":"PACKAGE","url":"https://github.com/ImageMagick/ImageMagick"},{"type":"WEB","url":"https://github.com/dlemstra/Magick.NET/releases/tag/14.10.2"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-08-12T03:51:17.155017222Z"}}