Every CVE Search/ Get API key

CVE-2026-54640

OpenRemote: XXE in KNXProtocol.startAssetImport() allows arbitrary file read via unprotected XMLInputFactory

7.6 HighFix available

OpenRemote is an open-source internet-of-things platform. Prior to 1.24.2, the KNXProtocol.startAssetImport method in agent/src/main/java/org/openremote/agent/protocol/knx/KNXProtocol.java processes 0.xml from an authenticated user's uploaded ETS project ZIP with Saxon TransformerFactoryImpl and XMLInputFactory parsers that permit external entity resolution. This incomplete remediation of CVE-2026-40882 leaves the KNX handler unprotected while the parallel Velbus handler is hardened, allowing a regular realm user to read files accessible to the JVM process or cause server-side requests. This issue is fixed in version 1.24.2.

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
Low
Availability
Low

Exploit likelihood

0.22%Unchanged since Oct 14, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.6

OpenRemote: XXE in KNXProtocol.startAssetImport() allows arbitrary file read via unprotected XMLInputFactory

OpenRemote is an open-source internet-of-things platform. Prior to 1.24.2, the KNXProtocol.startAssetImport method in agent/src/main/java/org/openremote/agent/protocol/knx/KNXProtocol.java processes 0.xml from an authenticated user's uploaded ETS project ZIP with Saxon TransformerFactoryImpl and XMLInputFactory parsers that permit external entity resolution. This incomplete remediation of CVE-2026-40882 leaves the KNX handler unprotected while the parallel Velbus handler is hardened, allowing a regular realm user to read files accessible to the JVM process or cause server-side requests. This issue is fixed in version 1.24.2.

Record
CVE-2026-54640
CVSS 3.1
7.6 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L
Weakness
CWE-611
Updated
2026-11-02
EUVDEUVD-2026-98841 7.6

OpenRemote is an open-source internet-of-things platform. Prior to 1.24.2, the KNXProtocol.startAssetImport method in agent/src/main/java/org/openremote/agent/protocol/knx/KNXProtocol.java processes 0.xml from an authenticated user's uploaded ETS project ZIP with Saxon TransformerFactoryImpl and XMLInputFactory parsers that permit external entity resolution. This incomplete remediation of CVE-2026-40882 leaves the KNX handler unprotected while the parallel Velbus handler is hardened, allowing a regular realm user to read files accessible to the JVM process or cause server-side requests. This issue is fixed in version 1.24.2.

Record
EUVD-2026-98841
CVSS 3.1
7.6 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L
Updated
2026-11-02
GitHub AdvisoriesGHSA-7v6w-c3f4-9wpq 7.6

OpenRemote has an incomplete fix for CVE-2026-40882: XXE in KNXProtocol.startAssetImport() allows arbitrary file read via unprotected XMLInputFactory

Summary

The fix for CVE-2026-40882 addressed only the Velbus asset import handler. The KNX asset import handler (KNXProtocol) processes user-uploaded ETS project ZIP files through Saxon XSLT and XMLInputFactory.newInstance() with no XXE protection, allowing any authenticated user to read arbitrary files from the server filesystem (e.g. /etc/passwd, openmrs-runtime.properties, cloud credential files).

Details

Incomplete patch

CVE-2026-40882 was fixed by introducing createSecureDocumentBuilderFactory() in AbstractVelbusProtocol.java with five XXE-blocking features. The parallel asset import handler in KNXProtocol.java was not updated and retains two unprotected XML parsing calls on the same user-controlled data.

Patched file — AbstractVelbusProtocol.java:

private DocumentBuilderFactory createSecureDocumentBuilderFactory() {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
    factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
    factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
    factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
    return factory;
}

Vulnerable file — KNXProtocol.java, lines 229–249:

// Line 229-230: reads 0.xml from user-uploaded ZIP
InputStream inputStream = KNXProtocol.class.getResourceAsStream(".../ets_calimero_group_name.xsl");
String xsd = IOUtils.toString(inputStream, StandardCharsets.UTF_8);

// Lines 233-245: Saxon XSLT — no XXE protection on the source document
TransformerFactory tfactory = new TransformerFactoryImpl();
Transformer transformer = tfactory.newTransformer(new StreamSource(new StringReader(xsd)));
transformer.transform(
    new StreamSource(new StringReader(xml)),  // xml = 0.xml from attacker's ZIP
    new StreamResult(writer));

// Line 249: XMLInputFactory — no SUPPORT_DTD=false, no IS_SUPPORTING_EXTERNAL_ENTITIES=false
try (final XmlReader r = XmlInputFactory.newInstance()
        .createXMLStreamReader(new StringReader(xml))) { ... }

Data flow

POST /api/{realm}/agent/{agentId}/import   (authenticated user, PR:L)
  → AgentResourceImpl.doProtocolAssetImport(fileData)
  → KNXProtocol.startAssetImport(byte[] fileData)
  → ZipInputStream reads 0.xml from attacker-controlled ETS ZIP
  → Saxon TransformerFactoryImpl.transform(StreamSource(0.xml))  ← XXE stage 1
  → XmlInputFactory.newInstance().createXMLStreamReader(xml)     ← XXE stage 2
  → external entity resolved → arbitrary file read

Comparison with patched code

| Handler | XML parser | DTD disabled | Status | |---|---|---|---| | AbstractVelbusProtocol | DocumentBuilderFactory | ✅ 5 features set | Patched (CVE-2026-40882) | | KNXProtocol | Saxon + XMLInputFactory | ❌ none set | Not patched |

PoC

No full OpenRemote installation required. The following reproduces the vulnerable XML processing chain using the exact same library versions.

Requirements: Java 17+, Maven 3.8+

pom.xml dependency:

<dependency>
    <groupId>net.sf.saxon</groupId>
    <artifactId>Saxon-HE</artifactId>
    <version>12.9</version>
</dependency>

Exploit.java:

import net.sf.saxon.TransformerFactoryImpl;
import javax.xml.stream.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import java.io.*;
import java.nio.file.*;

public class Exploit {
    public static void main(String[] args) throws Exception {

        // Sentinel file — proves arbitrary file read
        Path sentinel = Files.createTempFile("openremote_xxe_proof_", ".txt");
        String tag = "OPENREMOTE_KNX_XXE_" + System.currentTimeMillis();
        Files.writeString(sentinel, tag);

        String maliciousXml =
           …
Record
GHSA-7v6w-c3f4-9wpq
CVSS 3.1
7.6 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L
Weakness
CWE-611
Updated
2026-11-02
NVD 7.6

OpenRemote is an open-source internet-of-things platform. Prior to 1.24.2, the KNXProtocol.startAssetImport method in agent/src/main/java/org/openremote/agent/protocol/knx/KNXProtocol.java processes 0.xml from an authenticated user's uploaded ETS project ZIP with Saxon TransformerFactoryImpl and XMLInputFactory parsers that permit external entity resolution. This incomplete remediation of CVE-2026-40882 leaves the KNX handler unprotected while the parallel Velbus handler is hardened, allowing a regular realm user to read files accessible to the JVM process or cause server-side requests. This issue is fixed in version 1.24.2.

Record
CVE-2026-54640
CVSS 3.1
7.6 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L
Weakness
CWE-611
Updated
2026-11-02
OSV 7.6

OpenRemote: XXE in KNXProtocol.startAssetImport() allows arbitrary file read via unprotected XMLInputFactory

OpenRemote is an open-source internet-of-things platform. Prior to 1.24.2, the KNXProtocol.startAssetImport method in agent/src/main/java/org/openremote/agent/protocol/knx/KNXProtocol.java processes 0.xml from an authenticated user's uploaded ETS project ZIP with Saxon TransformerFactoryImpl and XMLInputFactory parsers that permit external entity resolution. This incomplete remediation of CVE-2026-40882 leaves the KNX handler unprotected while the parallel Velbus handler is hardened, allowing a regular realm user to read files accessible to the JVM process or cause server-side requests. This issue is fixed in version 1.24.2.

Record
CVE-2026-54640
CVSS 3.1
7.6 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L
Weakness
CWE-611
Updated
2026-11-02
OSVGHSA-7v6w-c3f4-9wpq 7.6

OpenRemote has an incomplete fix for CVE-2026-40882: XXE in KNXProtocol.startAssetImport() allows arbitrary file read via unprotected XMLInputFactory

Summary

The fix for CVE-2026-40882 addressed only the Velbus asset import handler. The KNX asset import handler (KNXProtocol) processes user-uploaded ETS project ZIP files through Saxon XSLT and XMLInputFactory.newInstance() with no XXE protection, allowing any authenticated user to read arbitrary files from the server filesystem (e.g. /etc/passwd, openmrs-runtime.properties, cloud credential files).

Details

Incomplete patch

CVE-2026-40882 was fixed by introducing createSecureDocumentBuilderFactory() in AbstractVelbusProtocol.java with five XXE-blocking features. The parallel asset import handler in KNXProtocol.java was not updated and retains two unprotected XML parsing calls on the same user-controlled data.

Patched file — AbstractVelbusProtocol.java:

private DocumentBuilderFactory createSecureDocumentBuilderFactory() {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
    factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
    factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
    factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
    return factory;
}

Vulnerable file — KNXProtocol.java, lines 229–249:

// Line 229-230: reads 0.xml from user-uploaded ZIP
InputStream inputStream = KNXProtocol.class.getResourceAsStream(".../ets_calimero_group_name.xsl");
String xsd = IOUtils.toString(inputStream, StandardCharsets.UTF_8);

// Lines 233-245: Saxon XSLT — no XXE protection on the source document
TransformerFactory tfactory = new TransformerFactoryImpl();
Transformer transformer = tfactory.newTransformer(new StreamSource(new StringReader(xsd)));
transformer.transform(
    new StreamSource(new StringReader(xml)),  // xml = 0.xml from attacker's ZIP
    new StreamResult(writer));

// Line 249: XMLInputFactory — no SUPPORT_DTD=false, no IS_SUPPORTING_EXTERNAL_ENTITIES=false
try (final XmlReader r = XmlInputFactory.newInstance()
        .createXMLStreamReader(new StringReader(xml))) { ... }

Data flow

POST /api/{realm}/agent/{agentId}/import   (authenticated user, PR:L)
  → AgentResourceImpl.doProtocolAssetImport(fileData)
  → KNXProtocol.startAssetImport(byte[] fileData)
  → ZipInputStream reads 0.xml from attacker-controlled ETS ZIP
  → Saxon TransformerFactoryImpl.transform(StreamSource(0.xml))  ← XXE stage 1
  → XmlInputFactory.newInstance().createXMLStreamReader(xml)     ← XXE stage 2
  → external entity resolved → arbitrary file read

Comparison with patched code

| Handler | XML parser | DTD disabled | Status | |---|---|---|---| | AbstractVelbusProtocol | DocumentBuilderFactory | ✅ 5 features set | Patched (CVE-2026-40882) | | KNXProtocol | Saxon + XMLInputFactory | ❌ none set | Not patched |

PoC

No full OpenRemote installation required. The following reproduces the vulnerable XML processing chain using the exact same library versions.

Requirements: Java 17+, Maven 3.8+

pom.xml dependency:

<dependency>
    <groupId>net.sf.saxon</groupId>
    <artifactId>Saxon-HE</artifactId>
    <version>12.9</version>
</dependency>

Exploit.java:

import net.sf.saxon.TransformerFactoryImpl;
import javax.xml.stream.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import java.io.*;
import java.nio.file.*;

public class Exploit {
    public static void main(String[] args) throws Exception {

        // Sentinel file — proves arbitrary file read
        Path sentinel = Files.createTempFile("openremote_xxe_proof_", ".txt");
        String tag = "OPENREMOTE_KNX_XXE_" + System.currentTimeMillis();
        Files.writeString(sentinel, tag);

        String maliciousXml =
           …
Record
GHSA-7v6w-c3f4-9wpq
CVSS 3.1
7.6 HighCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L
Weakness
CWE-611
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
io.openremote:openremote-agent
Maven
through 1.24.1
1.24.2
io.openremote:openremote-agent
Maven
before 1.24.2, plus listed versions
0.1.01.10.01.11.01.11.11.11.2
Show 45 moreShow less
1.11.31.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.22.01.22.11.23.01.23.11.24.01.24.11.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.5
1.24.2

History

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

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

In short

CVE-2026-54640 is a high vulnerability (CVSS 7.6) in Openremote, published July 6, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.22%, the 12th percentile. Fixed in io.openremote:openremote-agent 1.24.2.

References

This page doesn't list everything

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

MoveEnter Open