ArcadeDB: JavaScript Trigger OS Command Injection (RCE)
A database user with schema-admin rights can create a JavaScript trigger in ArcadeDB that calls Java's Runtime.exec() directly, running arbitrary OS commands on the server.
The problem
ArcadeDB's ScriptTriggerExecutor ran GraalVM JavaScript with HostAccess.ALL and listed java.lang.* in its allowed-packages, letting trigger scripts call Java.type("java.lang.Runtime") to reach the host JVM.
Trigger creation only required UPDATE_SCHEMA, a privilege below security-admin. Any schema admin could plant the trigger, then fire it by writing a matching record, getting full OS command execution as the server process user.
Proof of concept
A working proof-of-concept for this issue in com.arcadedb:arcadedb-engine, with the exact payload below.
-- Step 1: create the malicious trigger (requires 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: fire it by inserting a matching record
INSERT INTO Document SET x = 1GraalVM's Java.type() performs a host-class lookup that bypasses the reflection denylist. The engine configured HostAccess.ALL, so once java.lang.* was in the allowed-packages list the sandbox gave full access to java.lang.Runtime and java.lang.ProcessBuilder without restriction.
allowCreateProcess(false) only blocks GraalVM's own guest-side process API; it does not stop a script that reaches Runtime.exec() via a Java.type host lookup. The patch removes java.lang.* from the allowedPackages array in ScriptTriggerExecutor entirely, leaving only java.util.*, java.time.*, and java.math.*, which contain no execution primitives.
The fix
Upgrade to arcadedb-engine 26.7.2 or later. The release removes java.lang.* from the ScriptTriggerExecutor allowed-packages list. For defence in depth, consider switching from HostAccess.ALL to HostAccess.EXPLICIT and gating trigger creation at UPDATE_SECURITY rather than UPDATE_SCHEMA.
Related research
- high · 7.1CVE-2026-54077CVE-2026-54077: ArcadeDB IMPORT DATABASE SSRF and Local File Read
- highArcadeDB: Cross-Database IDOR on Time-Series, Batch, Prometheus, and Grafana Endpoints
- high · 7.5CVE-2026-44891CVE-2026-44891: netty-codec-stomp Unbounded Header Count DoS
- high · 7.5CVE-2026-59954CVE-2026-59954: Apollo ConfigService AccessKey Authentication Bypass via Non-Canonical appId