GHSA-g24f-mgc3-jwwc
HIGHGHSA-g24f-mgc3-jwwc is a high-severity (CVSS 7.6) vulnerability in io.openremote:openremote-manager. O3 Security confirms whether GHSA-g24f-mgc3-jwwc is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.
OpenRemote has XXE in Velbus Asset Import
Real-World Exposure
io.openremote:openremote-managerReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects Maven packages — download data is not available via public APIs for these ecosystems.
Description
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.xmland upload toSetupunderhttps://localhost/manager/?realm=<YOUR_REALM>#/assets/false/<ASSET_ID>. Chnage thefile:///etc/passwdto another file if yourpasswdis 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. <img width="1200" height="662" alt="image" src="https://github.com/user-attachments/assets/213f063d-98b6-4717-b98c-f4255952026b" />
If the file content reaches the limit, an error is thrown. <img width="1200" height="630" alt="image" src="https://github.com/user-attachments/assets/ee177a6b-2cb2-48ae-94df-c994ecb41429" />
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.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| ☕Maven | io.openremote:openremote-manager | all versions | 1.22.0 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for io.openremote:openremote-manager. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update io.openremote:openremote-manager to 1.22.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-g24f-mgc3-jwwc is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-g24f-mgc3-jwwc is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-g24f-mgc3-jwwc. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-g24f-mgc3-jwwc in your dependencies?
O3 detects GHSA-g24f-mgc3-jwwc across Maven dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.