insecure by designRSS
high

Draw.io Export Proxy Servlet Flaw Allows Path Traversal to Internal Backend Services

A path traversal vulnerability was uncovered in draw.io's export proxy servlet component, enabling attackers to query unintended internal endpoints on the backend export server. The root cause resides within `ExportProxyServlet.java` across lines 49 through 58, where the application extracts the trailing request path using `request.getPathInfo()`. The servlet splits the path on `/` separators and reconstructs a `proxyPath` variable without sanitizing traversal sequences. This unvalidated string is concatenated directly onto the base `EXPORT_URL` configuration to form the target URL via `new URL(exportUrl + proxyPath + queryString)` at line 85. Because Java's standard `URL` class does not perform path normalization, directory traversal payloads containing `..` escape the intended export path when resolved by the backend. Furthermore, the servlet forwards all original HTTP request headers and payloads directly to the internal destination without filtering. In typical containerized environments, the export server resides on the same internal Docker network as the draw.io application. Internal communication between these backend services lacks an authentication layer, meaning any reachable endpoint inherits implicit trust. An external actor can send a crafted request such as `GET /service/0/../../admin/config` to reach privileged internal routes like administrative interfaces or debug configurations. The recommended mitigation involves validating that path segments do not contain `..` or `%2e%2e`, normalizing the final target using `URI.normalize()`, and verifying that the final URI strictly matches the expected `EXPORT_URL` prefix.

Commentary

Path traversal vulnerabilities inside server-side proxy implementations are classic architectural blind spots. Modern web applications frequently stitch together microservices or containerized backends where the frontend web tier acts as an authenticated boundary, while internal services assume all incoming requests within the container mesh are benign. When a reverse proxy servlet naively forwards raw path strings and request bodies without canonicalization via `URI.normalize()`, an external client effectively gains direct HTTP reachability to internal-only endpoints. In standard self-hosted draw.io setups, this means an unauthenticated attacker could query arbitrary routes on the export container—potentially accessing internal configuration dumps, diagnostic metrics, or administrative toggles that were never designed to touch external traffic. Administrators managing self-hosted draw.io deployments should immediately audit their proxy layer and apply upstream updates addressing `ExportProxyServlet.java`. Additionally, network engineers should review ingress routing rules to drop incoming paths containing traversal patterns (such as `/../` and `%2e%2e`) at the edge reverse proxy or web application firewall (WAF) before traffic hits the application servlet.

The Quote to Remember

“The servlet takes a path from the incoming request URL and appends it directly to the export server's base URL without sanitizing .. segments, meaning an attacker can craft a URL that causes the backend to resolve to an entirely different path on the export server.”

← all articles