Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-76844

CVE-2026-76844: webpack-dev-middleware Path Traversal Flaw

CVE-2026-76844 is a path traversal flaw in webpack-dev-middleware that allows attackers to access files outside the intended directory when publicPath lacks a trailing slash. This post covers technical details, affected versions, impact, and mitigation steps.

Published:

CVE-2026-76844 Overview

CVE-2026-76844 is a path traversal vulnerability [CWE-22] in webpack-dev-middleware affecting versions from 5.3.4, 6.1.2, and 7.1.0 onward. The flaw lives in getFilenameFromUrl, where the traversal guard UP_PATH_REGEXP fails to catch .. sequences embedded inside a path segment. When publicPath is configured without a trailing slash, an attacker can craft a request such as GET /assets../.env against publicPath: /assets and read a file one directory above outputPath. This represents an incomplete fix for CVE-2024-29180.

Critical Impact

Unauthenticated remote attackers can read arbitrary files one directory above the middleware outputPath when writeToDisk is true or a custom outputFileSystem is configured, exposing source, configuration, and secret files such as .env.

Affected Products

  • webpack-dev-middleware versions 5.3.4 through the last 5.x release
  • webpack-dev-middleware versions 6.1.2 through the last 6.x release
  • webpack-dev-middleware versions 7.1.0 and later, including 8.x releases up to 8.1.1

Discovery Timeline

  • 2026-08-24 - CVE-2026-76844 published to NVD
  • 2026-08-26 - Last updated in NVD database

Technical Details for CVE-2026-76844

Vulnerability Analysis

The middleware resolves incoming requests through getFilenameFromUrl, which tests the request pathname against a traversal guard and then slices it at a fixed character offset. The guard applies UP_PATH_REGEXP to path.normalize("./${pathname}") and only matches .. sequences that stand as a whole path segment. Containment against the configured public path is checked using pathname.startsWith(publicPathPathname), and the final file path is built as path.join(outputPath, pathname.slice(publicPathPathname.length)).

The mismatch between these two operations creates the traversal. A request path like /assets../.env contains no standalone .. segment, so the regex guard permits it. The startsWith("/assets") check also passes. The slice then removes the fixed prefix length, yielding ../.env, which path.join resolves one level above outputPath.

Reading a file from that path requires the middleware to be backed by the physical filesystem. This occurs when writeToDisk is true or a custom outputFileSystem is supplied. The default memfs volume holds only build output and is not affected.

Root Cause

The traversal guard and the offset slice were introduced as the fix for CVE-2024-29180 but operate on inconsistent segment semantics. UP_PATH_REGEXP treats .. only as a full segment, while the slice-based containment check treats publicPath as a raw string prefix. Any publicPath without a trailing slash lets an attacker append characters that keep the prefix intact yet cross into a new logical segment after the slice.

Attack Vector

An unauthenticated attacker sends a single HTTP GET request. Traversal depth is limited to one directory because URL parsing collapses any separately delimited .. segment before the guard runs. The default publicPath value of "auto" resolves to / and is not affected. Exploitation requires a development server that persists build output to disk or uses a custom output filesystem.

Refer to the VulnCheck advisory on path traversal via offset slice and the GitHub Security Advisory GHSA-wr3j-pwj9-hqq6 for a full technical breakdown.

Detection Methods for CVE-2026-76844

Indicators of Compromise

  • HTTP access logs containing request paths that concatenate the configured publicPath prefix with .. characters and no intervening slash, for example /assets../, /static../, or /public../.
  • Successful 200 OK responses to requests whose paths reference sensitive filenames such as .env, package.json, or id_rsa served from a development host.
  • Reads of files that reside outside the configured outputPath directory, correlated with webpack-dev-middleware process activity.

Detection Strategies

  • Inspect reverse-proxy and application logs for URL patterns matching the regex \/[A-Za-z0-9_-]+\.\.\/ on hosts running webpack-dev-middleware.
  • Audit build and deployment pipelines to identify projects that set writeToDisk: true or configure a custom outputFileSystem, then confirm publicPath has a trailing slash.
  • Alert on any external network exposure of Node.js development servers, since webpack-dev-middleware is intended for local use only.

Monitoring Recommendations

  • Instrument file-access telemetry on developer workstations and CI runners to flag reads of dotfiles above known project output directories.
  • Track anomalous outbound access to development ports (commonly 3000, 8080, 9000) originating from non-loopback interfaces.
  • Correlate web-server access logs with process telemetry to attribute suspicious path-traversal requests to the middleware process.

How to Mitigate CVE-2026-76844

Immediate Actions Required

  • Upgrade webpack-dev-middleware to a patched release that follows the fix for CVE-2026-76844. Review the GitHub Security Advisory GHSA-wr3j-pwj9-hqq6 for fixed version numbers.
  • Audit every webpack.config.js and devServer configuration and ensure publicPath values end with / or are left at the default "auto".
  • Disable writeToDisk and remove custom outputFileSystem settings unless required, since the default in-memory filesystem is not exploitable.
  • Restrict the development server to localhost bindings and block external access at the network boundary.

Patch Information

The maintainers released fixed versions on the webpack-dev-middleware GitHub repository. Consult the webpack-dev-middleware project page and the middleware source at v8.1.1 for the specific commit that hardens getFilenameFromUrl.

Workarounds

  • Append a trailing slash to every configured publicPath value, for example change /assets to /assets/.
  • Leave publicPath unset so it resolves to the default "auto" value, which is not affected.
  • Front the development server with a reverse proxy that normalizes URLs and rejects paths containing .. in any position before forwarding.
bash
# Configuration example: ensure publicPath ends with a slash
# webpack.config.js
module.exports = {
  output: {
    path: '/var/app/dist',
    publicPath: '/assets/'  // trailing slash prevents the traversal
  },
  devServer: {
    devMiddleware: {
      writeToDisk: false     // keep build output in memfs when possible
    },
    host: '127.0.0.1'        // avoid binding to public interfaces
  }
};

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.