CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2025-68271
10.00.32%

Ground Control to Major Pwn: Unauthenticated RCE in OpenC3 COSMOS

Alon Barad
Alon Barad
Software Engineer

Feb 20, 2026·6 min read·3 visits

PoC Available

Executive Summary (TL;DR)

OpenC3 COSMOS, a command and control system for satellites, contains a critical 10.0 CVSS vulnerability. It uses Ruby's `eval()` to parse array-like strings in API requests. Because this parsing happens before authentication, anyone can send a crafted JSON-RPC packet to execute code as the server user. Patch immediately to version 6.10.2.

A critical unauthenticated Remote Code Execution (RCE) vulnerability in OpenC3 COSMOS allows attackers to execute arbitrary commands on the host server. The flaw stems from the insecure usage of Ruby's `eval()` method during the parsing of JSON-RPC parameters, specifically within the `cmd` method handler. Crucially, parameter parsing occurs before authentication checks, allowing unprivileged attackers to gain full control over the satellite command and control system.

The Hook: Houston, We Have a Problem

OpenC3 COSMOS is the kind of software that makes a security researcher's ears perk up. It isn't just another CRUD app; it is 'Command and Control' software designed for embedded systems, test equipment, and yes, satellites. It is the digital nervous system for mission-critical hardware. When you are controlling hardware that moves at 17,000 miles per hour, the stakes are naturally higher than your average e-commerce store.

So, when a vulnerability drops in OpenC3 with a CVSS score of a perfect 10.0, it is not a drill. CVE-2025-68271 is an unauthenticated Remote Code Execution (RCE) flaw. In plain English, this means an attacker can walk up to the mission control dashboard's API, whisper a few magic words, and instantly gain the privileges of the user running the server. No password, no token, no invite required.

What makes this specific vulnerability fascinating—and terrifying—is how pedestrian the root cause is. It isn't a complex heap overflow or a race condition in a kernel driver. It is a textbook failure in handling user input in a dynamic language. It is the digital equivalent of leaving the keys to the Space Shuttle under the doormat.

The Flaw: The 'Eval' of All Evils

To understand this bug, you have to look at how Ruby developers sometimes solve the problem of 'Type Juggling.' The application receives data via a JSON-RPC API. Sometimes that data comes in as a string, but the application really wants it to be an Array. A safe way to do this would be to use a JSON parser. The unsafe way—the 'hold my beer' way—is to use eval().

Deep inside openc3/lib/openc3/core_ext/string.rb, the developers extended the native String class with a helper method called convert_to_value. This method acts as a heuristic scanner. It looks at a string and guesses what it should be. If the string is wrapped in square brackets, like "[1, 2, 3]", the code assumes it is an array.

Here is the fatal mistake: rather than parsing that string safely, the code simply passed the entire string to Ruby's eval() function. eval() executes the string as valid Ruby code. This is the ultimate sin in dynamic languages. If an attacker controls the string going into eval(), they control the CPU.

The Code: Anatomy of a Disaster

Let's look at the smoking gun. This is the code responsible for the vulnerability. It is a classic example of convenience over security.

Vulnerable Code (Pre-Patch):

# openc3/lib/openc3/core_ext/string.rb
 
def convert_to_value
  if self.is_int?
    return to_i
  elsif self.is_float?
    return to_f
  elsif self.is_array? # Checks if string starts with [
    return eval(self)  # <--- GAME OVER
  else
    return self
  end
end

The is_array? check is merely a regex looking for square brackets. It doesn't validate the contents of the brackets. So, if I send "[ system('rm -rf /') ]", the application sees the brackets, says 'Looks like an array to me!', and hands it to eval.

The fix involves swapping the dangerous eval for a safe serializer. In the patched version (6.10.2), they switched to YAML.safe_load, which parses the structure without executing code.

Fixed Code (Post-Patch):

# openc3/lib/openc3/core_ext/string.rb
 
elsif self.is_array? or self.is_object?
  return YAML.safe_load(self)
end

The Exploit: Bypassing the Guards

You might be asking: 'But surely I need to be logged in to send commands to a satellite controller?' That would be logical. However, logic often takes a backseat to execution flow bugs. The vulnerability exists in the processing of the request parameters, which happens before the authorization middleware kicks in.

The attack vector targets the JSON-RPC endpoint. When the server receives a POST request, it attempts to route the command. Specifically, the cmd method requires parameters to be parsed so the system knows which target packet to construct. The server triggers convert_to_value on the attacker's input in order to figure out what the input is.

The Attack Chain:

  1. Attacker sends a POST to /api/rpc.
  2. Payload sets the method to cmd and the params to ["#{ id }"].
  3. Server sees the brackets and triggers eval().
  4. Ruby interpolates the string, executes id via backticks, and substitutes the result.
  5. Server then checks authentication. It sees you aren't logged in and returns a 401 Unauthorized.
  6. Attacker ignores the 401 because the code already ran.

Here is what that flow looks like visually:

The Impact: From Orbit to Owners

The impact here is total system compromise (CVSS 10.0). Since OpenC3 often runs with elevated privileges to interface with hardware drivers or serial ports, the attacker likely inherits those permissions.

In a best-case scenario, the attacker installs a crypto miner on your ground station server. In a worst-case scenario, they can inject commands into the telemetry stream. If this system is controlling a thermal vacuum chamber, a robotic arm, or an actual satellite link, the physical consequences could be catastrophic.

Furthermore, because the exploit leaves very little trace other than a 'failed' login attempt in the logs, it is an ideal candidate for stealthy persistence. An attacker could patch the vulnerability themselves after gaining entry to lock out other hackers, leaving the admins none the wiser.

The Fix: Safe Landing

If you are running OpenC3 COSMOS versions 5.0.0 through 6.10.1, you are sitting on a powder keg. The remediation is straightforward: Update to version 6.10.2 immediately.

If you cannot update right now (perhaps you are in the middle of a critical mission), you must implement WAF rules to block this attack vector. You specifically want to filter JSON-RPC traffic containing the cmd method where parameters contain Ruby interpolation syntax (#{) or backticks.

However, WAF rules are band-aids. The real fix is ensuring that user input is never treated as executable code. This vulnerability serves as a stark reminder: eval is not a parsing library. If you need to deserialize data, use a deserializer. If you need to run code, rethink your architecture.

Official Patches

OpenC3Official GitHub Security Advisory and Patch Information

Technical Appendix

CVSS Score
10.0/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
EPSS Probability
0.32%
Top 45% most exploited

Affected Systems

OpenC3 COSMOS 5.0.0OpenC3 COSMOS 6.10.1

Affected Versions Detail

Product
Affected Versions
Fixed Version
OpenC3 COSMOS
OpenC3
>= 5.0.0, <= 6.10.16.10.2
AttributeDetail
CWE IDCWE-95 (Eval Injection)
CVSS v3.110.0 (Critical)
Attack VectorNetwork (Pre-Auth)
ImpactRemote Code Execution (RCE)
Vulnerable MethodString#convert_to_value
SinkKernel.eval()

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1059.006Command and Scripting Interpreter: Python/Ruby
Execution
CWE-95
Improper Neutralization of Directives in Dynamically Evaluated Code ('Eval Injection')

The product receives input from an upstream component, but it does not neutralize or incorrectly neutralizes code syntax before using the input in a dynamic evaluation call (e.g. 'eval').

Known Exploits & Detection

GitHub Security AdvisoryAdvisory containing PoC payload structure.

Vulnerability Timeline

Vulnerability Published
2026-01-13
Patch Released (v6.10.2)
2026-01-13

References & Sources

  • [1]GHSA-w757-4qv9-mghp: Critical RCE in OpenC3
  • [2]NVD - CVE-2025-68271

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.