PostCSS Path Traversal Vulnerability via Source Map Auto-Loading
A path traversal vulnerability (GHSA-r28c-9q8g-f849) in PostCSS versions up to 8.5.17 allows an unauthenticated attacker to disclose arbitrary `.map` file contents from a vulnerable server by crafting a `sourceMappingURL` comment in user-submitted CSS, leading to sensitive information exposure if the processed output is returned.
A significant path traversal vulnerability, identified as GHSA-r28c-9q8g-f849, has been discovered in PostCSS, a popular CSS processing tool, affecting versions up to 8.5.17. This flaw stems from the tool's default behavior of auto-detecting and attempting to load "previous source maps" specified in /*# sourceMappingURL=... */ comments within CSS text. An attacker can manipulate these comments with directory traversal sequences (e.g., ../../../) or absolute paths to bypass intended directory restrictions, coercing PostCSS into reading arbitrary .map files from the filesystem. If the application then returns the processed result.map (a common practice in build pipelines), the attacker can extract sensitive information contained within the sourcesContent field of these disclosed .map files. This vulnerability requires no authentication and can be triggered by submitting specially crafted CSS to any service that processes untrusted CSS with PostCSS without explicitly setting the map: false option.
Attack Chain
- An attacker identifies a service that accepts user-submitted CSS and processes it using PostCSS, leveraging its default
postcss().process()behavior. - The attacker crafts a malicious CSS input containing a
/*# sourceMappingURL=../../../../some/other/app/dist/bundle.js.map */comment. - The service invokes
postcss().process()on the attacker's CSS, with themapoption left at its default (true). - During processing, PostCSS's
loadMap()function attempts to resolve thesourceMappingURLannotation. - The
path.join()operation, combined withloadFile(), processes the traversal sequence, allowing access to.mapfiles outside the intended directory. - PostCSS successfully reads the arbitrary
.mapfile (e.g.,bundle.js.map) from the server's filesystem. - The
sourcesContentfield from the read.mapfile, which often contains actual source code, is merged into theresult.mapobject generated by PostCSS. - The vulnerable service, following typical build pipeline behavior, outputs or returns the
result.mapto the attacker, leading to the disclosure of sensitive file contents.
Impact
This vulnerability leads to the disclosure of contents from arbitrary .map files accessible by the PostCSS process's privileges on the filesystem. The impact is significant as .map files frequently contain embedded source code and project structure information which, if exposed, can reveal intellectual property, internal logic, or aid in further attacks. Any application processing untrusted CSS without explicitly disabling source map generation (via map: false) is vulnerable. No authentication or user interaction beyond submitting the malicious CSS is required. The specific number of victims is unknown, but given PostCSS's widespread use in web development, a large number of applications could be at risk.
Recommendation
- Upgrade PostCSS to version 8.5.18 or later as soon as patches become available to remediate the path traversal vulnerability documented in GHSA-r28c-9q8g-f849.
- For immediate mitigation or if upgrading is not feasible, configure any application processing untrusted CSS with PostCSS to explicitly set the
map: falseoption in thepostcss().process()call. This prevents PostCSS from attempting to load source maps and nullifies the exploitation vector described in this brief. - Review the application's handling of
result.mapto ensure that if source maps are legitimately generated, they are not inadvertently exposed to untrusted entities.