Jun 17, 2026·7 min read·8 visits
A path parsing discrepancy between Node's URL parser and the raw string checks in the 'ws' library allows proxy middleware in webpack-dev-server to intercept local HMR WebSocket traffic. This bypasses Host/Origin security controls and leaks client cookies to proxy targets.
webpack-dev-server (WDS) is vulnerable to an Origin Validation Error (CWE-346) and a Confused Deputy vulnerability (CWE-441) due to path normalization discrepancies in its upgrade handling. When a proxy is configured with a broad context and WebSocket support is enabled, the proxy middleware intercepts internal Hot Module Replacement (HMR) WebSocket upgrade requests. This forwards the browser's credentials (such as Cookies and Origin headers) to the backend target, bypassing built-in security controls and corrupting the WebSocket connection.
The front-end utility webpack-dev-server (WDS) is an HTTP-based development server designed to host local web applications. It implements a Hot Module Replacement (HMR) framework to dynamically inject code updates into running applications without requiring full page refreshes. Communication between the browser client and the local compilation runner relies on a dedicated WebSocket interface. By default, this socket executes on specific local paths, such as /ws or /sockjs-node depending on the configured version.
To facilitate integration with backend components, developers often configure a local reverse proxy using the devServer.proxy directive. This proxy is powered by the http-proxy-middleware engine and runs on the same underlying HTTP server instance. When a developer creates a wildcard or broad proxy configuration (such as proxying the root path / with WebSocket support enabled via ws: true), the proxy's upgrade handlers are bound globally to the server. Without strict isolation, the proxy interceptor can hijack the internal development server's own HMR socket upgrades.
This vulnerability occurs because the pre-filter mechanism in WDS fails to reliably identify and bypass HMR requests before they are routed to the user-configured proxy. By intercepting these internal frames, WDS acts as a confused deputy. It forwards local administrative WebSocket handshake packets directly to the configured backend target. This action bypasses the Host header check and CORS validation layers built directly into WDS.
The root cause of this vulnerability lies in a critical path-normalization discrepancy between two software layers: the pre-filter router in webpack-dev-server and the route matcher in the underlying ws library. When a client initiates a WebSocket connection, an HTTP GET request containing Upgrade: websocket headers is dispatched to the server. The WDS middleware evaluates whether the request matches the local Hot Module Replacement path (hmrPath) to decide if it must skip proxying.
In versions prior to 5.2.5, WDS extracted the request path from the incoming message using Node.js's native URL class. This parser normalizes URL sequences. Specifically, it resolves relative path steps, collapses duplicate adjacent slashes (e.g., rewriting //ws to / under certain hostname configurations), decodes percent-encoded character sequences, and strips trailing forward slashes. This normalization behavior is standard for general web servers but differs from low-level protocol drivers.
The underlying ws WebSocket library (specifically inside its WebSocketServer#shouldHandle method) does not normalize incoming paths. Instead, it performs a strict, raw, case-sensitive comparison of the raw string stored in req.url with the query string manually stripped. It does not normalize duplicate slashes, decode percent encodings, or ignore case variants. Consequently, a request sent to //ws, /%77%73, or /WS fails the raw comparison inside ws, but is normalized to /ws by the pre-filter URL parser. This path mismatch allows malicious or deformed client requests to evade the pre-filter and get captured by the broader proxy middleware, or to trigger a dual-upgrade handler race condition.
In versions of webpack-dev-server prior to 5.2.5, the upgrade pre-filter used the standard URL constructor to parse the path. The vulnerable implementation resolved paths as follows:
// Vulnerable routing block inside lib/Server.js
const { pathname } = new URL(req.url, "http://0.0.0.0");
if (pathname === hmrPath) {
return; // Skip proxying and let the local WebSocket server handle it
}
// If the path was modified (e.g. //ws), pathname became "/" and missed the block
proxyUpgrade(req, socket, head);This logic causes a parsing differential. Because new URL('//ws', 'http://0.0.0.0') is parsed with ws treated as the hostname and / as the path, pathname resolves to /. Since / does not match hmrPath (which is typically /ws), the filter does not return early. Instead, the request drops down to proxyUpgrade(). However, the raw req.url is still string-matched against the proxy targets.
To address this discrepancy, the maintainers in commit 948d5e6089bebcd801dac2cbe3ed4f80b64f117a removed the URL parser entirely. They aligned the string extraction mechanism exactly with the native parsing behavior of the ws library:
// Patched upgrade handling in lib/Server.js (v5.2.5)
(this.server).on("upgrade", (req, socket, head) => {
if (hmrPath && typeof req.url === "string") {
// Extract the raw path prefix up to the query delimiter
const queryIndex = req.url.indexOf("?");
const pathname =
queryIndex !== -1 ? req.url.slice(0, queryIndex) : req.url;
// Match the exact raw character sequence processed by the ws library
if (pathname === hmrPath) {
return; // Early return correctly blocks the proxy handler
}
}
proxyUpgrade(req, socket, head);
});This simple slice operation guarantees that WDS only blocks the proxy when the string matches the exact format that the ws library will accept. Any invalid or variant paths that would be ignored by ws are consistently left to the proxy, preventing dual-handling on mismatched paths.
An attack occurs when a client browser connects to a webpack-dev-server instance configured with a wildcard or broad proxy path, such as / with ws: true. When WDS receives a client connection attempting an upgrade to the HMR socket, the proxy middleware intercepts the HTTP handshake. Because the pre-filter parsing is bypassed, the proxy processes the upgrade and forwards the entire request payload to the designated backend server target.
This forwarding behavior creates an information disclosure vector. The proxy forwards the browser client's cookies (including HttpOnly session tokens) and the Origin header directly to the backend target. Under normal circumstances, these credentials should remain restricted to the local development server context. This allows any unauthenticated or unauthorized backend proxy target to receive credentials intended solely for the local environment.
Additionally, this bypass neutralizes the dev-server's built-in Host and Origin validation checks. These checks prevent Cross-Origin WebSocket Hijacking (COSH) and DNS rebinding attacks. Because the proxy captures the connection before the server applies validation rules, those security checks are bypassed. Finally, if the request is accepted by both the local HMR WebSocket server and the proxy middleware, both systems attempt to write handshake headers and upgrade frames to the same TCP socket. This dual-handling violates RFC 6455 and immediately corrupts the stream, leading to connection failures and development server instability.
To fully resolve CVE-2026-9595, users should upgrade webpack-dev-server to version 5.2.5 or higher. This update changes the HMR path-matching logic to match the exact string processing used by the ws dependency, resolving the parsing differential.
For systems where an immediate upgrade is not feasible, developers must configure mitigation strategies to reduce exposure. The most effective mitigation is to narrow the scope of the proxy middleware's routing contexts. Wildcard contexts (such as /) should be avoided. Instead, define specific prefix paths to ensure that the proxy only captures designated backend routes:
// Remediated Proxy Configuration with restricted paths
module.exports = {
devServer: {
proxy: [
{
context: '/api',
target: 'http://localhost:3000',
ws: false
}
]
}
};If the application does not rely on backend WebSocket services, the proxy's socket integration should be disabled by setting the ws parameter to false (or omitting it). This prevents the proxy from binding to the HTTP server's upgrade event emitter, blocking the attack vector.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
webpack-dev-server webpack | < 5.2.5 | 5.2.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-346, CWE-441 |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 5.3 (Medium) |
| EPSS Score | 0.00163 (Percentile: 5.81%) |
| Impact | Credential Leakage, Host Security Bypass, Connection Corruption |
| Exploit Status | poc |
| KEV Status | Not Listed |
The software does not properly validate or normalizes the origin of a request, or improperly forwards transactions to downstream hosts on behalf of a client without checking validation rules.
CVE-2026-5038 is a critical denial of service vulnerability in the Node.js Multer middleware. When utilizing the diskStorage engine, connection termination or validation failures leave partial files orphaned on the local filesystem due to stream-destruction signal propagation failures in Node's piping mechanism. Remote unauthenticated attackers can exploit this to fill server disks and induce system crashes.
CVE-2026-5079 is a high-severity Denial of Service (DoS) vulnerability in the Node.js package 'multer'. The vulnerability resides in how its internal dependency, 'append-field', processes deeply nested bracket structures in multipart form field names. If an attacker submits a field name with an excessive number of nested brackets, the parsing process crashes the Node.js runtime environment or exhausts system resources, causing a complete denial of service.
An information disclosure vulnerability exists in OpenClaw before version 2026.5.12. The issue resides within the streamable-http Model Context Protocol (MCP) server integration, where the application client automatically forwards operator-configured custom headers during cross-origin HTTP redirects. If an attacker controls or compromises a configured remote MCP endpoint, they can issue redirect responses to exfiltrate highly sensitive data, such as API keys or tenant-routing credentials, to unauthorized external origins.
A critical preprocessing mismatch exists in vLLM's multimodal image pipeline before commit cf1c90672404548aa3bc51f92c4745576a65ee26. The vulnerability occurs because the engine loads user-submitted images and passes them to underlying Vision-Language Models (VLMs) without normalizing their EXIF orientation metadata or fully resolving complex transparency structures. This gap creates a perception desynchronization vulnerability where the physical pixel grid processed by the AI model differs significantly from how the image is visually rendered to human moderators or frontend applications. Attackers can exploit this mismatch to perform silent prompt injections, bypass safety moderation systems, or execute adversarial jailbreaks.
An incorrect authorization vulnerability exists in the open-source workflow automation platform n8n within the Evaluation Test Runs Controller. In deployments utilizing Advanced Permissions, an authenticated user assigned a low-privilege project:viewer role can bypass configured permission policies. This allows the unauthorized user to execute, terminate, or delete workflow evaluation test runs by exploiting misconfigured API scope validations that map read-only scopes to mutating endpoints.
An authenticated security-bypass vulnerability in n8n allows users with workflow creation or modification privileges to bypass the Python AST security validator. By circumventing AST validation logic, attackers can execute arbitrary statements, access the task executor's root module namespace, and disclose sensitive host environment variables on self-hosted instances.