highJul 16, 2026

ArcadeDB: JavaScript Trigger OS Command Injection (RCE)

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

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.

Packagecom.arcadedb:arcadedb-engine
Ecosystemmaven
Affected< 26.7.2
Fixed in26.7.2

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.

sql
-- 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 = 1

GraalVM'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.

Reporter not attributed.

References: [1][2][3]

Related research