CVE-2026-54640: 
Java vulnerability analysis and mitigation

Overview

CVE-2026-54640 is an XML External Entity (XXE) injection vulnerability in OpenRemote's KNXProtocol asset import handler that allows any authenticated user to read arbitrary files from the server filesystem. It represents an incomplete fix for CVE-2026-40882, which patched only the Velbus asset import handler (AbstractVelbusProtocol.java) while leaving the parallel KNX handler (KNXProtocol.java) unprotected. Affected versions are io.openremote:openremote-agent and io.openremote:openremote-manager ≤ 1.24.1; version 1.24.2 contains the patch. The vulnerability was published on June 12, 2026, and carries a CVSS v3.1 base score of 7.6 (High) (GitHub Advisory, OpenRemote Advisory).

Technical details

The root cause is CWE-611 (Improper Restriction of XML External Entity Reference). When a user uploads an ETS project ZIP file via POST /api/{realm}/agent/{agentId}/import, KNXProtocol.startAssetImport() extracts 0.xml from the archive and passes it through two unprotected XML parsing stages: (1) a Saxon TransformerFactoryImpl XSLT transform with no FEATURE_SECURE_PROCESSING or ACCESS_EXTERNAL_DTD restrictions, and (2) XMLInputFactory.newInstance().createXMLStreamReader() with neither SUPPORT_DTD=false nor IS_SUPPORTING_EXTERNAL_ENTITIES=false set. Both parsers resolve external entities defined in attacker-controlled XML, enabling arbitrary local file reads. The fix for CVE-2026-40882 introduced createSecureDocumentBuilderFactory() with five XXE-blocking features in AbstractVelbusProtocol.java but did not apply equivalent hardening to KNXProtocol.java, leaving two unprotected parsing calls on the same user-controlled data (GitHub Advisory, Patch Commit).

Impact

Successful exploitation allows any authenticated user (no administrator privileges required) to read arbitrary files accessible to the JVM process user, including /etc/passwd, application configuration files containing database credentials or API keys, and cloud provider credential files. Additionally, the unprotected parsers can be leveraged for Server-Side Request Forgery (SSRF) to probe internal services or cloud metadata endpoints (e.g., http://169.254.169.254/). The vulnerability is present in KNXProtocol, a built-in handler shipped with every OpenRemote installation that includes the agent module, meaning no special configuration is required for exposure (GitHub Advisory, OpenRemote Advisory).

Exploitability

A public proof-of-concept (PoC) is included in the GitHub advisory, demonstrating both exploitation stages (Saxon TransformerFactoryImpl and XMLInputFactory) using Java 17+ and Maven 3.8+, with verified output on JDK 21/Linux confirming arbitrary file read. Exploitation requires only a valid authenticated session (low-privilege user in any realm) and no special server configuration. No evidence of in-the-wild exploitation, threat actor attribution, or CISA KEV catalog listing has been reported at this time. The CVE status is listed as "Reserved" and no EPSS score is currently published (GitHub Advisory).

Exploitation steps

  1. Obtain authenticated access: Register or compromise any low-privilege user account in an OpenRemote realm that has access to the Manager API.
  2. Craft a malicious ETS project ZIP: Create a ZIP archive containing a file at P-0001/0.xml with an XXE payload referencing a target local file, e.g.:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>&xxe;</root>
  1. Upload the malicious ZIP: Send an authenticated HTTP POST request to the import endpoint:
POST /api/{realm}/agent/{agentId}/import
Content-Type: multipart/form-data
[attach malicious .knxproj ZIP]
  1. Trigger XXE via Saxon XSLT (Stage 1): The server's KNXProtocol.startAssetImport() reads 0.xml from the ZIP and passes it to TransformerFactoryImpl.transform() without XXE protection, resolving the external entity.
  2. Trigger XXE via XMLInputFactory (Stage 2): The same XML is subsequently parsed by XMLInputFactory.newInstance().createXMLStreamReader() with no DTD or external entity restrictions, providing a second resolution path.
  3. Retrieve exfiltrated data: The contents of the referenced file are embedded in the server's response or can be exfiltrated via an out-of-band HTTP request to an attacker-controlled server by referencing an external DTD that triggers a secondary request containing the file contents (GitHub Advisory, OpenRemote Advisory).

Indicators of compromise

  • Network: Unexpected outbound HTTP/HTTPS requests from the OpenRemote server to external or internal IP addresses (e.g., 169.254.169.254 for cloud metadata, or attacker-controlled hosts) originating from the JVM process; DNS lookups for attacker-controlled domains triggered by the server.
  • Logs: OpenRemote access logs showing repeated POST requests to /api/{realm}/agent/{agentId}/import with .knxproj or ZIP file uploads from non-administrative accounts; Java exception stack traces in application logs related to XML parsing or XSLT transformation errors.
  • File System: Unexpected temporary files created by the JVM process in system temp directories (e.g., files matching openremote_xxe_proof_*.txt pattern from PoC testing).
  • Process: Unusual network connections initiated by the OpenRemote Java process to internal services or metadata endpoints not part of normal KNX/IoT operations (GitHub Advisory).

Mitigation and workarounds

Upgrade io.openremote:openremote-agent and io.openremote:openremote-manager to version 1.24.2, which introduces createSecureTransformerFactory() (setting FEATURE_SECURE_PROCESSING, ACCESS_EXTERNAL_DTD, and ACCESS_EXTERNAL_STYLESHEET to empty) and validateSecureXml() (using a hardened XMLInputFactory with SUPPORT_DTD=false and IS_SUPPORTING_EXTERNAL_ENTITIES=false) in KNXProtocol.java. No official configuration-based workaround is provided; if upgrading immediately is not possible, consider restricting access to the /api/{realm}/agent/{agentId}/import endpoint to trusted administrator accounts only at the network or application layer (Patch Commit, GitHub Advisory).

Community reactions

The advisory was published by OpenRemote maintainer ebariaux on June 12, 2026, and credited researcher dyingman1 for the report. The vulnerability was added to the GitHub Advisory Database on July 6, 2026. No significant broader media coverage, social media discussion, or notable third-party researcher commentary has been identified beyond the official advisory (GitHub Advisory).

Additional resources


Source: This report was generated using AI

Related Java vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-102695HIGH8.2
  • Java logoJava
  • org.omnifaces:omnifaces
NoYesOct 14, 2026
CVE-2026-102834HIGH7.5
  • Java logoJava
  • org.bytedeco:javacv
NoYesOct 16, 2026
CVE-2026-97370HIGH7.5
  • Java logoJava
  • com.github.junrar:junrar
NoYesOct 15, 2026
CVE-2026-54683MEDIUM6.5
  • Java logoJava
  • nl.nl-portal:documenten-api
NoYesOct 15, 2026
CVE-2026-55414MEDIUM5.3
  • Java logoJava
  • nl.nl-portal:form
NoYesOct 15, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management