
Remote Code Execution (RCE) in Yamcs Mission Control System via Java Statement Injection in Yarch SQL Double-Quoted IdentifiersRemote Code Execution (RCE) in Yamcs Mission Control System via Java Statement Injection in Yarch SQL Double-Quoted Identifiers
Non-weaponized proof of concept and technical documentation for CVE-2026-55511, an authenticated Java code-injection vulnerability in the Yamcs StreamSQL aggregate-expression compiler.
| Field | Value |
|---|---|
| Product | Yamcs (org.yamcs:yamcs-core) |
| Advisory | GHSA-3g44-3m7x-cgg2 |
| Weakness | CWE-94: Improper Control of Generation of Code |
| Severity | Critical, CVSS 3.1: 9.1 |
| Vector | CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H |
| Required privilege | SystemPrivilege.ControlArchiving |
| Fixed releases | Yamcs 5.13.2 and 5.12.8 |
| Mainline patch | b65a3d78178ba99a58b753feda6ecc3b5a694f13 |
Yamcs accepts double-quoted names for StreamSQL objects and, in affected releases, permits almost any character inside those names. Aggregate expressions such as sum(...) dynamically construct Java source using column names and compile that source with Janino SimpleCompiler.
The vulnerable code applies only minimal name sanitization before placing a column name into a generated Java identifier. An authenticated user with ControlArchiving can therefore create a crafted quoted column name, reach the aggregate compiler through POST /api/archive/{instance}:executeSql, and execute attacker-influenced Java inside the Yamcs server JVM.
This crosses the intended Yamcs authorization boundary: ControlArchiving permits archive, table, and stream management, but does not intentionally grant arbitrary Java execution on the server.
| Release line | Affected | Fixed |
|---|---|---|
| 5.13.x | 5.13.1 and earlier | 5.13.2 |
| 5.12.x | 5.12.7 and earlier | 5.12.8 |
Upgrade to Yamcs 5.13.2, 5.12.8, or a later supported release.
The vulnerable data flow is:
POST /api/archive/{instance}:executeSql
-> TableApi.executeSql
-> Yarch StreamSQL parser
-> double-quoted object name
-> SelectExpression aggregate binding
-> SumExpression.aggregateFillCode_newData
-> Expression.fillCode_InputDefVars
-> CompilableAggregateExpression.getCompiledAggregate
-> Janino SimpleCompiler.cook
-> attacker-influenced Java executes in the Yamcs JVM
Three conditions combine to create the issue:
S_DOUBLE_QUOTED_IDENTIFIER grammar accepts any character except CR, LF, and ".Expression.fillCode_InputDefVars derives a Java variable name from the column name. Its sanitizeName helper replaces only / and -.This leaves Java syntax characters such as semicolons, whitespace, parentheses, assignment operators, and dots available in the generated newData(Tuple) method. Unlike a bare-expression path, the aggregate method provides reachable statement context in which injected statements can compile and execute.
Exploitation requires an authenticated account holding SystemPrivilege.ControlArchiving. An account without that privilege is rejected by the TableApi.executeSql authorization check.
Successful exploitation runs Java with the privileges of the Yamcs service process. Depending on deployment isolation, this can affect the confidentiality, integrity, and availability of mission data and the host environment. The issue is not an unauthenticated RCE and does not by itself elevate the Yamcs process beyond its operating-system or container permissions.
The included poc.py is intentionally non-weaponized:
javac and java) for the benign marker testcd /path/to/yamcs
python3 /path/to/poc.py \
--json /tmp/evidence.json \
--log /tmp/crash_evidence.log \
--expect-crash
Expected indicators:
source_chain_confirmed=true
generated_source_injection_present=true
marker_executed=true
evidence/evidence.json: structured source-chain and Java-model resultsevidence/crash_evidence.log: concise validation logThe included evidence was produced against Yamcs source commit 98a05e95461207c143e4297ec4bb1b5a76e9cb19. It confirms the vulnerable source chain, generated-source injection, and benign marker execution.
The upstream fix is titled Avoid RCE through double-quoted identifiers:
b65a3d78178ba99a58b753feda6ecc3b5a694f13, released in 5.13.28c1070b12c0a6c003903325cb2a1013347e2dbde, released in 5.12.8The core change restricts double-quoted identifiers from an almost unrestricted character set:
< S_DOUBLE_QUOTED_IDENTIFIER: "\"" (~["\n","\r","\""])* "\"" >
to an allowlist of letters, digits, $, _, #, and .:
< S_DOUBLE_QUOTED_IDENTIFIER: "\"" (<LETTER> | <DIGIT> | <SPECIAL_CHARS>)+ "\"" >
This rejects the statement-separating and expression-building characters required by the reported injection before the name reaches Java code generation. The patch also updates generated parser files, documentation, and a related test.
The restriction may affect existing quoted object names containing spaces or non-allowlisted punctuation. Review StreamSQL schemas and automation before upgrading or backporting.
CVE-2026-55511 is a separate entry point from CVE-2026-44632 / GHSA-524g-x36v-9wm6. CVE-2026-44632 concerns JavaExprAlgorithmExecutionFactory, is reached through mission-database algorithm override functionality, and is gated by ChangeMissionDatabase.
This issue is in org.yamcs.yarch.streamsql, is reached through executeSql, and is gated by ControlArchiving. The earlier 5.13.0 / 5.12.7 algorithm-path fix did not modify the StreamSQL compiler or its quoted-identifier handling.
VULNERABILITY_REPORT.md: expanded vulnerability reportPATCH_ANALYSIS.md: detailed upstream patch analysis and compatibility notesUse this material only in systems you own or are explicitly authorized to test.