OpenRemote has XXE in Velbus Asset Import
Date: 2026-04
Affected: maven/io.openremote:openremote-manager
Attack vector: ssrf
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-40882
CWE: CWE-611
CVSS: 7.6 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L)

### Summary The Velbus asset import path parses attacker-controlled XML without explicit XXE hardening. An authenticated user who can call the import endpoint may trigger XML external entity processing, which can lead to server-side file disclosure and SSRF. The target file must be less than 1023 characters. ### Details Velbus import uses `DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(...)` on untrusted XML input, without explicit safeguards to disable DTD/external entities. ```154:165:agent/src/main/java/org/openremote/agent/protocol/velbus/AbstractVelbusProtocol.java @Override public Future<Void> startAssetImport(byte[] fileData, Consumer<AssetTreeNode[]> assetConsumer) { return executorService.submit(() -> { Document xmlDoc; try { String xmlStr = new String(fileData, StandardCharsets.UTF_8); LOG.info("Parsing VELBUS project file"); xmlDoc = DocumentBuilderFactory .newInstance() .newDocumentBuilder() .parse(new InputSource(new StringReader(xmlStr))); ``` Expanded `Caption` content is propagated into created asset names: ```193:198:agent/src/main/java/org/openremote/agent/protocol/velbus/AbstractVelbusProtocol.java String name = module.getElementsByTagName("Caption").item(0).getTextContent(); name = isNullOrEmpty(name) ? deviceType.toString() : name; // TODO


Mitigations:

Architectural layers (MAESTRO):