Command injection in Harmony trajectory-subsetter (subset.shape GeoJSON) gives any Earthdata user remote code execution (RCE) as root on harmony.earthdata.nasa.gov

Disclosed by
cl45h
Summary by cl45h

Command injection in the NASA Harmony trajectory-subsetter service allowed any
holder of a free Earthdata Login account to execute arbitrary OS commands as
root inside the production Harmony processing environment.

Root cause

The service builds the subsetter command line as a string. The user supplied
GeoJSON shapefile is re-serialized with json.dumps and interpolated into a
single quoted argument:

  binary_parameters["--boundingshape"] = f"'{bounding_shape}'"

json.dumps does not escape single quotes, so a quote character inside any
GeoJSON property closes the argument. The resulting string was then executed
through subprocess.Popen(command, shell=True), so the injected text was
interpreted by the shell.

Impact

A single multipart request with a crafted subset.shape polygon achieved
command execution as uid=0 inside the production container. The only
precondition is a free, self service Earthdata Login account, so the attack
surface was effectively public. Confirmed severity: CVSS 3.1 8.8
(AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H), triaged P1.

Testing scope

Activity was limited to read only confirmation that command execution occurs
(id, whoami, hostname, uname). No NASA mission or user data was accessed,
modified or destroyed, no persistence or interactive shell was established,
and no access to any other system was attempted.

Remediation

NASA fixed the issue in the public repository
nasa/harmony-trajectory-subsetter, release v1.0.11 (2026-08-28): arguments are
now passed as an array with shell=False, and the shape value is no longer
wrapped in quotes in the command string.

Timeline

2026-07-03 Reported
2026-07-03 Triaged and replicated by Bugcrowd
2026-07-06 Accepted as valid by NASA
2026-08-28 Fix released publicly (v1.0.11)
2026-09-02 Resolved

Activity