CVE-2026-77602
OpenC3 COSMOS: Authenticated remote code execution via the user-writable config overlay (table definitions, cmd/tlm definitions, and script suites)
OpenC3 COSMOS provides the functionality needed to send commands to and receive data from one or more embedded systems. From 5.1.0 until 7.3.0, authenticated non-administrator users can write content under targets_modified/ that is later executed by multiple configuration paths below the intended code-execution privilege tier. Table and command or telemetry definitions are processed through ConfigParser, PacketConfig, GENERIC_READ_CONVERSION, or GENERIC_WRITE_CONVERSION, allowing ERB rendering or Ruby and Python evaluation, while openc3-cosmos-script-runner-api/scripts/run_suite_analysis.rb executes suite procedure files through require. Storage uploads, screen saves, and script creation can place content in the overlay, and triggering table processing, a cmd/tlm reload, or suite analysis executes the content in cmd-tlm-api, decom microservices, or Script Runner with access to internal credentials and data. This issue is fixed in version 7.3.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
9.9
OpenC3 COSMOS: Authenticated remote code execution via the user-writable config overlay (table definitions, cmd/tlm definitions, and script suites)
OpenC3 COSMOS provides the functionality needed to send commands to and receive data from one or more embedded systems. From 5.1.0 until 7.3.0, authenticated non-administrator users can write content under targets_modified/ that is later executed by multiple configuration paths below the intended code-execution privilege tier. Table and command or telemetry definitions are processed through ConfigParser, PacketConfig, GENERIC_READ_CONVERSION, or GENERIC_WRITE_CONVERSION, allowing ERB rendering or Ruby and Python evaluation, while openc3-cosmos-script-runner-api/scripts/run_suite_analysis.rb executes suite procedure files through require. Storage uploads, screen saves, and script creation can place content in the overlay, and triggering table processing, a cmd/tlm reload, or suite analysis executes the content in cmd-tlm-api, decom microservices, or Script Runner with access to internal credentials and data. This issue is fixed in version 7.3.0.
- Record
CVE-2026-77602- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-94
- Updated
- 2026-11-02
EUVDEUVD-2026-85566
9.9
OpenC3 COSMOS provides the functionality needed to send commands to and receive data from one or more embedded systems. From 5.1.0 until 7.3.0, authenticated non-administrator users can write content under targets_modified/ that is later executed by multiple configuration paths below the intended code-execution privilege tier. Table and command or telemetry definitions are processed through ConfigParser, PacketConfig, GENERIC_READ_CONVERSION, or GENERIC_WRITE_CONVERSION, allowing ERB rendering or Ruby and Python evaluation, while openc3-cosmos-script-runner-api/scripts/run_suite_analysis.rb executes suite procedure files through require. Storage uploads, screen saves, and script creation can place content in the overlay, and triggering table processing, a cmd/tlm reload, or suite analysis executes the content in cmd-tlm-api, decom microservices, or Script Runner with access to internal credentials and data. This issue is fixed in version 7.3.0.
- Record
EUVD-2026-85566- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-jjq7-m736-w977
9.9
OpenC3 COSMOS: Authenticated remote code execution via the user-writable config overlay (table definitions, cmd/tlm definitions, and script suites)
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).
Details
Root cause. TargetFile.body (Ruby openc3/lib/openc3/utilities/target_file.rb, Python openc3/python/openc3/utilities/target_file.py) reads {scope}/targets_modified/{name} before {scope}/targets/{name}. The storage-upload endpoint storage_controller.rb get_upload_presigned_request is gated at system_set and exempts targets_modified/ and tmp/ from its admin check (so a write there is not admin-gated); for a target path it additionally calls authorize_bucket_path, which in the permission-enforcing edition requires tlm on the target, while in the open-source edition authorize ignores the permission string entirely. screens_controller.rb create (system_set) stores its request body verbatim under targets_modified/<target>/screens/. So a non-admin can place files in the overlay. The config subsystem then executes them.
Sink 1, ERB. ConfigParser#parse_file renders the file as ERB before parsing (run_erb defaults to true):
# openc3/lib/openc3/config/config_parser.rb:402
output = ERB.new(File.read(filename)...comment_erb(), trim_mode: "-").result(...)
Reached for table definitions via tables_controller.rb -> Table.get_definitions -> TableConfig.process_file -> parse_file, and for cmd/tlm definitions via System.setup_targets (system.rb, whose overlay loop copies targets_modified/<T>/cmd_tlm/* over the read-only files) -> PacketConfig#process_file -> parse_file.
Sink 2, GENERIC conversion. PacketConfig/TableConfig build a GenericConversion from a GENERIC_READ_CONVERSION_START .. END / GENERIC_WRITE_CONVERSION_START .. END block, and GenericConversion#call evaluates it (independent of ERB):
# openc3/lib/openc3/conversions/generic_conversion.rb (call)
eval(@code_to_eval)
# Python openc3/python/openc3/conversions/generic_conversion.py (call): compile()/exec()/eval()
The read conversion fires on tables#report/load and during telemetry decom; the write conversion fires on tables#generate and on restore_defaults.
Sink 3,…
- Record
GHSA-jjq7-m736-w977- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-94
- Updated
- 2026-11-02
NVD
9.9
OpenC3 COSMOS provides the functionality needed to send commands to and receive data from one or more embedded systems. From 5.1.0 until 7.3.0, authenticated non-administrator users can write content under targets_modified/ that is later executed by multiple configuration paths below the intended code-execution privilege tier. Table and command or telemetry definitions are processed through ConfigParser, PacketConfig, GENERIC_READ_CONVERSION, or GENERIC_WRITE_CONVERSION, allowing ERB rendering or Ruby and Python evaluation, while openc3-cosmos-script-runner-api/scripts/run_suite_analysis.rb executes suite procedure files through require. Storage uploads, screen saves, and script creation can place content in the overlay, and triggering table processing, a cmd/tlm reload, or suite analysis executes the content in cmd-tlm-api, decom microservices, or Script Runner with access to internal credentials and data. This issue is fixed in version 7.3.0.
- Record
CVE-2026-77602- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-94
- Updated
- 2026-11-02
OSV
9.9
OpenC3 COSMOS: Authenticated remote code execution via the user-writable config overlay (table definitions, cmd/tlm definitions, and script suites)
OpenC3 COSMOS provides the functionality needed to send commands to and receive data from one or more embedded systems. From 5.1.0 until 7.3.0, authenticated non-administrator users can write content under targets_modified/ that is later executed by multiple configuration paths below the intended code-execution privilege tier. Table and command or telemetry definitions are processed through ConfigParser, PacketConfig, GENERIC_READ_CONVERSION, or GENERIC_WRITE_CONVERSION, allowing ERB rendering or Ruby and Python evaluation, while openc3-cosmos-script-runner-api/scripts/run_suite_analysis.rb executes suite procedure files through require. Storage uploads, screen saves, and script creation can place content in the overlay, and triggering table processing, a cmd/tlm reload, or suite analysis executes the content in cmd-tlm-api, decom microservices, or Script Runner with access to internal credentials and data. This issue is fixed in version 7.3.0.
- Record
CVE-2026-77602- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-94
- Updated
- 2026-11-02
OSVGHSA-jjq7-m736-w977
9.9
OpenC3 COSMOS: Authenticated remote code execution via the user-writable config overlay (table definitions, cmd/tlm definitions, and script suites)
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).
Details
Root cause. TargetFile.body (Ruby openc3/lib/openc3/utilities/target_file.rb, Python openc3/python/openc3/utilities/target_file.py) reads {scope}/targets_modified/{name} before {scope}/targets/{name}. The storage-upload endpoint storage_controller.rb get_upload_presigned_request is gated at system_set and exempts targets_modified/ and tmp/ from its admin check (so a write there is not admin-gated); for a target path it additionally calls authorize_bucket_path, which in the permission-enforcing edition requires tlm on the target, while in the open-source edition authorize ignores the permission string entirely. screens_controller.rb create (system_set) stores its request body verbatim under targets_modified/<target>/screens/. So a non-admin can place files in the overlay. The config subsystem then executes them.
Sink 1, ERB. ConfigParser#parse_file renders the file as ERB before parsing (run_erb defaults to true):
# openc3/lib/openc3/config/config_parser.rb:402
output = ERB.new(File.read(filename)...comment_erb(), trim_mode: "-").result(...)
Reached for table definitions via tables_controller.rb -> Table.get_definitions -> TableConfig.process_file -> parse_file, and for cmd/tlm definitions via System.setup_targets (system.rb, whose overlay loop copies targets_modified/<T>/cmd_tlm/* over the read-only files) -> PacketConfig#process_file -> parse_file.
Sink 2, GENERIC conversion. PacketConfig/TableConfig build a GenericConversion from a GENERIC_READ_CONVERSION_START .. END / GENERIC_WRITE_CONVERSION_START .. END block, and GenericConversion#call evaluates it (independent of ERB):
# openc3/lib/openc3/conversions/generic_conversion.rb (call)
eval(@code_to_eval)
# Python openc3/python/openc3/conversions/generic_conversion.py (call): compile()/exec()/eval()
The read conversion fires on tables#report/load and during telemetry decom; the write conversion fires on tables#generate and on restore_defaults.
Sink 3,…
- Record
GHSA-jjq7-m736-w977- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-94
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
openc3RubyGems |
5.1.0 to 7.2.1 | 7.3.0 |
openc3RubyGems |
5.1.0 up to 7.3.0, plus listed versions 5.1.15.10.05.10.15.11.05.11.1 Show 45 moreShow less5.11.25.11.35.12.05.13.05.14.05.14.15.14.25.15.05.15.15.15.25.16.05.16.15.16.25.17.05.17.15.18.05.19.05.2.05.20.05.3.05.4.05.4.15.4.25.4.3.pre.beta05.5.05.5.0.pre.beta05.5.15.5.25.5.2.pre.beta05.6.05.6.15.7.05.7.25.8.05.8.15.9.05.9.16.0.06.0.16.0.26.1.06.10.06.10.16.10.26.10.3 |
7.3.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-77602 is a critical vulnerability (CVSS 9.9) in Openc3 Cosmos, published September 23, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.72%, the 54th percentile. Fixed in openc3 7.3.0.
References
github.com/OpenC3/cosmos/security/advisories/GHSA-jjq7-m736-w977
github.com/OpenC3/cosmos/pull/3488
github.com/OpenC3/cosmos/commit/71943352a28128ef3e7e894319d97a656b5cd4f2
github.com/OpenC3/cosmos/commit/7a1538a4626f82c0d1540fcaa27ffdcbbd71ff81
github.com/advisories/GHSA-jjq7-m736-w977
github.com/CVEProject/cvelistV5/tree/main/cves/2026/77xxx/CVE-2026-77602.json
nvd.nist.gov/vuln/detail/CVE-2026-77602
github.com/OpenC3/cosmos
Left out here: 27 versions and the rest of 2 source descriptions. The JSON record has them.