Every CVE Search/ Get API key

CVE-2026-39842

OpenRemote is Vulnerable to Expression Injection

10.0 CriticalPublic exploitFix available

OpenRemote is an open-source IoT platform. Versions 1.21.0 and below contain two interrelated expression injection vulnerabilities in the rules engine that allow arbitrary code execution on the server. The JavaScript rules engine executes user-supplied scripts via Nashorn's ScriptEngine.eval() without sandboxing, class filtering, or access restrictions, and the authorization check in RulesResourceImpl only restricts Groovy rules to superusers while leaving JavaScript rules unrestricted for any user with the write:rules role. Additionally, the Groovy rules engine has a GroovyDenyAllFilter security filter that is defined but never registered, as the registration code is commented out, rendering the SandboxTransformer ineffective for superuser-created Groovy rules. A non-superuser attacker with the write:rules role can create JavaScript rulesets that execute with full JVM access, enabling remote code execution as root, arbitrary file read, environment variable theft including database credentials, and complete multi-tenant isolation bypass to access data across all realms. This issue has been fixed in version 1.22.0.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
High

Exploit likelihood

0.92%Up 0.8 points since Apr 15, 2026
90%50%10%1%

What each source reports

CVE List Score used 10.0

OpenRemote is Vulnerable to Expression Injection

OpenRemote is an open-source IoT platform. Versions 1.21.0 and below contain two interrelated expression injection vulnerabilities in the rules engine that allow arbitrary code execution on the server. The JavaScript rules engine executes user-supplied scripts via Nashorn's ScriptEngine.eval() without sandboxing, class filtering, or access restrictions, and the authorization check in RulesResourceImpl only restricts Groovy rules to superusers while leaving JavaScript rules unrestricted for any user with the write:rules role. Additionally, the Groovy rules engine has a GroovyDenyAllFilter security filter that is defined but never registered, as the registration code is commented out, rendering the SandboxTransformer ineffective for superuser-created Groovy rules. A non-superuser attacker with the write:rules role can create JavaScript rulesets that execute with full JVM access, enabling remote code execution as root, arbitrary file read, environment variable theft including database credentials, and complete multi-tenant isolation bypass to access data across all realms. This issue has been fixed in version 1.22.0.

Record
CVE-2026-39842
CVSS 3.1
10.0 CriticalCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Weakness
CWE-94, CWE-917
Updated
2026-11-02
EUVDEUVD-2026-22806 10.0

OpenRemote is an open-source IoT platform. Versions 1.21.0 and below contain two interrelated expression injection vulnerabilities in the rules engine that allow arbitrary code execution on the server. The JavaScript rules engine executes user-supplied scripts via Nashorn's ScriptEngine.eval() without sandboxing, class filtering, or access restrictions, and the authorization check in RulesResourceImpl only restricts Groovy rules to superusers while leaving JavaScript rules unrestricted for any user with the write:rules role. Additionally, the Groovy rules engine has a GroovyDenyAllFilter security filter that is defined but never registered, as the registration code is commented out, rendering the SandboxTransformer ineffective for superuser-created Groovy rules. A non-superuser attacker with the write:rules role can create JavaScript rulesets that execute with full JVM access, enabling remote code execution as root, arbitrary file read, environment variable theft including database credentials, and complete multi-tenant isolation bypass to access data across all realms. This issue has been fixed in version 1.22.0.

Record
EUVD-2026-22806
CVSS 3.1
10.0 CriticalCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Updated
2026-11-02
GitHub AdvisoriesGHSA-7mqr-33rv-p3mp 9.9

Expression Injection in OpenRemote

Summary

The OpenRemote IoT platform's rules engine contains two interrelated critical expression injection vulnerabilities that allow an attacker to execute arbitrary code on the server, ultimately achieving full server compromise.

  • Unsandboxed Nashorn JavaScript Engine: JavaScript rules are executed via Nashorn's ScriptEngine.eval() with user-supplied script content and no sandboxing, class filtering, or access restrictions. Critically, any non-superuser with the write:rules role can create JavaScript rulesets.
  • Inactive Groovy Sandbox: The Groovy rules engine has a GroovyDenyAllFilter security filter that is defined but never registered (the registration code is commented out), rendering the SandboxTransformer ineffective. While Groovy rules are restricted to superusers, the absence of sandboxing violates the principle of defense in depth.

Details

Attacker-Controllable Source-to-Sink Paths

There are two non-superuser and two superuser exploitable attack paths from the REST API entry point to final code execution. (JavaScript × Realm/Asset + Groovy × Realm/Asset) The most critical path is detailed below.

Path 1: Unsandboxed JavaScript Expression Injection via Realm Ruleset (Non-Superuser Exploitable)

RulesetDeployment.java L368:

Object result = scriptEngine.eval(script, engineScope);

The Nashorn JavaScript engine is initialized without a ClassFilter, allowing Java.type() to access any JVM class — including java.lang.Runtime (for RCE), java.io.FileReader (for file read), and java.lang.System (for env theft).

RulesResourceImpl.java L309 (and L331, L359, L412, L437):

// VULNERABLE: only restricts Groovy, JavaScript completely unrestricted
if (ruleset.getLang() == Ruleset.Lang.GROOVY && !isSuperUser()) {
    throw new WebApplicationException(Response.Status.FORBIDDEN);
}

Non-superuser attackers with only the write:rules role can submit arbitrary JavaScript rules that execute with full JVM access.

┌─────────────────────────────────────────────────────────────────────────────────────────┐
│                          SOURCE → SINK Complete Data Flow                                │
├─────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                         │
│  ① HTTP REQUEST (Source / Entry Point)                                                   │
│  POST /api/{realm}/rules/realm                                                          │
│  Content-Type: application/json                                                         │
│  Body: { "type":"realm", "lang":"JAVASCRIPT",                                           │
│          "rules":"<MALICIOUS_SCRIPT>", ... }     ← Attacker-controlled malicious script  │
│                                                                                         │
│                              ↓ JAX-RS Deserialization                                    │
│                                                                                         │
│  ② RulesResource.createRealmRuleset()                                                   │
│     model/.../rules/RulesResource.java:153-158                                          │
│     @POST @Path("realm") @RolesAllowed("write:rules")                                   │
│     Interface: long createRealmRuleset(RequestParams, @Valid RealmRuleset ruleset)       │
│     JSON body → RealmRuleset object (Jackson deserialization)         …
Record
GHSA-7mqr-33rv-p3mp
CVSS 3.1
9.9 CriticalCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Weakness
CWE-94, CWE-917
Updated
2026-11-02
NVD 9.9

OpenRemote is an open-source IoT platform. Versions 1.21.0 and below contain two interrelated expression injection vulnerabilities in the rules engine that allow arbitrary code execution on the server. The JavaScript rules engine executes user-supplied scripts via Nashorn's ScriptEngine.eval() without sandboxing, class filtering, or access restrictions, and the authorization check in RulesResourceImpl only restricts Groovy rules to superusers while leaving JavaScript rules unrestricted for any user with the write:rules role. Additionally, the Groovy rules engine has a GroovyDenyAllFilter security filter that is defined but never registered, as the registration code is commented out, rendering the SandboxTransformer ineffective for superuser-created Groovy rules. A non-superuser attacker with the write:rules role can create JavaScript rulesets that execute with full JVM access, enabling remote code execution as root, arbitrary file read, environment variable theft including database credentials, and complete multi-tenant isolation bypass to access data across all realms. This issue has been fixed in version 1.22.0.

Record
CVE-2026-39842
CVSS 3.1
9.9 CriticalCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Weakness
CWE-94, CWE-917
Updated
2026-11-02
OSV 9.9

OpenRemote is Vulnerable to Expression Injection

OpenRemote is an open-source IoT platform. Versions 1.21.0 and below contain two interrelated expression injection vulnerabilities in the rules engine that allow arbitrary code execution on the server. The JavaScript rules engine executes user-supplied scripts via Nashorn's ScriptEngine.eval() without sandboxing, class filtering, or access restrictions, and the authorization check in RulesResourceImpl only restricts Groovy rules to superusers while leaving JavaScript rules unrestricted for any user with the write:rules role. Additionally, the Groovy rules engine has a GroovyDenyAllFilter security filter that is defined but never registered, as the registration code is commented out, rendering the SandboxTransformer ineffective for superuser-created Groovy rules. A non-superuser attacker with the write:rules role can create JavaScript rulesets that execute with full JVM access, enabling remote code execution as root, arbitrary file read, environment variable theft including database credentials, and complete multi-tenant isolation bypass to access data across all realms. This issue has been fixed in version 1.22.0.

Record
CVE-2026-39842
CVSS 3.1
9.9 CriticalCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Weakness
CWE-917, CWE-94
Updated
2026-11-02
OSVGHSA-7mqr-33rv-p3mp 9.9

Expression Injection in OpenRemote

Summary

The OpenRemote IoT platform's rules engine contains two interrelated critical expression injection vulnerabilities that allow an attacker to execute arbitrary code on the server, ultimately achieving full server compromise.

  • Unsandboxed Nashorn JavaScript Engine: JavaScript rules are executed via Nashorn's ScriptEngine.eval() with user-supplied script content and no sandboxing, class filtering, or access restrictions. Critically, any non-superuser with the write:rules role can create JavaScript rulesets.
  • Inactive Groovy Sandbox: The Groovy rules engine has a GroovyDenyAllFilter security filter that is defined but never registered (the registration code is commented out), rendering the SandboxTransformer ineffective. While Groovy rules are restricted to superusers, the absence of sandboxing violates the principle of defense in depth.

Details

Attacker-Controllable Source-to-Sink Paths

There are two non-superuser and two superuser exploitable attack paths from the REST API entry point to final code execution. (JavaScript × Realm/Asset + Groovy × Realm/Asset) The most critical path is detailed below.

Path 1: Unsandboxed JavaScript Expression Injection via Realm Ruleset (Non-Superuser Exploitable)

RulesetDeployment.java L368:

Object result = scriptEngine.eval(script, engineScope);

The Nashorn JavaScript engine is initialized without a ClassFilter, allowing Java.type() to access any JVM class — including java.lang.Runtime (for RCE), java.io.FileReader (for file read), and java.lang.System (for env theft).

RulesResourceImpl.java L309 (and L331, L359, L412, L437):

// VULNERABLE: only restricts Groovy, JavaScript completely unrestricted
if (ruleset.getLang() == Ruleset.Lang.GROOVY && !isSuperUser()) {
    throw new WebApplicationException(Response.Status.FORBIDDEN);
}

Non-superuser attackers with only the write:rules role can submit arbitrary JavaScript rules that execute with full JVM access.

┌─────────────────────────────────────────────────────────────────────────────────────────┐
│                          SOURCE → SINK Complete Data Flow                                │
├─────────────────────────────────────────────────────────────────────────────────────────┤
│                                                                                         │
│  ① HTTP REQUEST (Source / Entry Point)                                                   │
│  POST /api/{realm}/rules/realm                                                          │
│  Content-Type: application/json                                                         │
│  Body: { "type":"realm", "lang":"JAVASCRIPT",                                           │
│          "rules":"<MALICIOUS_SCRIPT>", ... }     ← Attacker-controlled malicious script  │
│                                                                                         │
│                              ↓ JAX-RS Deserialization                                    │
│                                                                                         │
│  ② RulesResource.createRealmRuleset()                                                   │
│     model/.../rules/RulesResource.java:153-158                                          │
│     @POST @Path("realm") @RolesAllowed("write:rules")                                   │
│     Interface: long createRealmRuleset(RequestParams, @Valid RealmRuleset ruleset)       │
│     JSON body → RealmRuleset object (Jackson deserialization)         …
Record
GHSA-7mqr-33rv-p3mp
CVSS 3.1
9.9 CriticalCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
Weakness
CWE-917, CWE-94
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
io.openremote:openremote-manager
Maven
through 1.21.0
1.22.0
io.openremote:openremote-manager
Maven
before 1.22.0, plus listed versions
1.10.01.11.01.11.11.11.21.11.3
Show 42 moreShow less
1.12.01.12.11.12.31.13.01.13.11.14.01.15.01.15.11.15.21.16.11.17.01.17.11.17.21.17.31.18.01.19.01.2.01.2.11.2.21.2.31.2.41.20.01.20.11.20.21.21.01.3.01.3.11.3.21.3.31.3.41.3.51.4.01.5.01.6.01.6.21.6.31.6.41.6.51.7.01.8.01.8.11.9.0
1.22.0

Public exploits

Links only. Every CVE stores no exploit code.

Public exploits
SourceLinkDate
PoC in GitHubkeraattin/CVE-2026-398422026-04-17

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV, PoC in GitHub

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-39842 is a critical vulnerability (CVSS 10.0) in Openremote, published April 14, 2026. Public exploit code exists. EPSS puts the chance of exploitation in the next 30 days at 0.92%, the 60th percentile. Fixed in io.openremote:openremote-manager 1.22.0.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open