OpenC3 COSMOS - Authenticated remote code execution via the user-writable config overlay (table definitions, cmd/tlm definitions, and script suites)
Published: July 11, 2026
SECURITY IDENTIFIERS
- CVE: CVE-2026-77602 (NVD)
- GHSA: GHSA-jjq7-m736-w977
GEM
SEVERITY
CVSS v3.x: 9.9 (Critical)
UNAFFECTED VERSIONS
< 5.1.0
PATCHED VERSIONS
>= 7.2.1
DESCRIPTION
Summary
COSMOS reads configuration from a user-writable overlay (targets_modified/)
before the read-only plugin-installed targets/ tree, and the config
subsystem executes code on those files: ConfigParser renders every
file as ERB by default, a GENERIC_READ_CONVERSION /
GENERIC_WRITE_CONVERSION block is evaluated as code by
GenericConversion (Ruby and Python), and the Script Runner suite
analysis requires a procedure file. An authenticated user can write
into targets_modified/ below the admin tier (the storage-upload
endpoint exempts that area from the admin gate, and the screen-save
endpoint stores its body verbatim there), so the same root cause is
reachable through several features, each giving arbitrary code
execution on a COSMOS server.
Three vulnerable routes were identified, all reachable by an
authenticated non-admin user (in the open-source edition authorize
ignores the permission string, so any authenticated user qualifies):
-
Table definitions (immediate).
tables#generate|report|loadreads a definition fromtargets_modified/and ERB-renders it and evaluates itsGENERIC_*_CONVERSIONblock in thecmd-tlm-apicontainer. -
Command/telemetry definitions (persistent). A file written to
targets_modified/<TARGET>/cmd_tlm/is overlaid bySystem.setup_targetsand processed byPacketConfigin the decom/multi microservices: ERB-rendered in the Ruby implementation, and GENERIC-evaluated in both the Ruby and Python implementations (the PythonConfigParserdoes not run ERB). It executes on the next microservice (re)start. -
Script Runner suites (immediate). A procedure written to
targets_modified/<TARGET>/procedures/isrequired by the suite analysis, reachable at the read-onlyscript_viewtier throughscripts#bodyandrunning_script#show(the analysis subprocess is spawned whenOPENC3_SERVICE_PASSWORDis configured, which it is in the shipped.env).
Impact
Arbitrary code execution as the openc3 user in the cmd-tlm-api
container and the per-target decom microservices and the script-runner.
Those processes hold the Redis and bucket credentials and sit on the
internal service network, so the executed code acts with that authority
over configuration, telemetry, and command data across scopes. The
API is served through Traefik, which the shipped compose binds to
127.0.0.1:2900, so a default single-host install is reachable only
from the host; a multi-user deployment exposes the web port, and the
AV:N rating reflects that standard remote-operator exposure.
All paths require valid authentication, and the triggering permissions
(system/system_set/script_view) are below the admin/script_run/
lugin-install tiers where COSMOS gates code execution. In the
open-source edition authorize checks only token validity and does
not enforce the permission string, so any authenticated user can
perform these requests.
RELATED
- https://nvd.nist.gov/vuln/detail/CVE-2026-77602
- https://rubygems.org/gems/openc3/versions/7.2.1
- https://github.com/OpenC3/cosmos/releases/tag/v7.2.1
- https://github.com/OpenC3/cosmos/pull/3488
- https://github.com/OpenC3/cosmos/commit/71943352a28128ef3e7e894319d97a656b5cd4f2
- https://github.com/OpenC3/cosmos/commit/7a1538a4626f82c0d1540fcaa27ffdcbbd71ff81
- https://advisories.gitlab.com/gem/openc3/CVE-2026-77602
- https://osv.dev/vulnerability/GHSA-jjq7-m736-w977
- https://github.com/OpenC3/cosmos/security/advisories/GHSA-jjq7-m736-w977
- https://github.com/advisories/GHSA-jjq7-m736-w977
