CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-fxqj-rqcc-2cmp: PostCSS: incomplete fix of GHSA-6g55-p6wh-862q — attacker-controlled sourceMappingURL reads arbitrary .map files when `from` is unset

mediumCVE-2026-69153
Summary The fix for GHSA-6g55-p6wh-862q added a guard in lib/previous-map.js PreviousMap.loadFile() that restricts an attacker-controlled sourceMappingURL (from a CSS comment) to a .map extension and, for untrusted maps, rejects .. traversal and absolute paths. The traversal/absolute rejection is nested inside if (cssFile) { ... }. When PostCSS is invoked without the from option, cssFile is falsy and that branch is skipped, leaving only the .map extension check. PreviousMap is constructed by lib/input.js whenever pathAvailable && sourceMapAvailable (under Node with source-map available), independent of opts.from/opts.map (the constructor returns early only for opts.map === false). So postcss([]).process(css) on attacker CSS reaches loadFile with cssFile undefined, and an attacker /*# sourceMappingURL=/abs/path/x.map */ (or ../-traversing path) is read via readFileSync. When the file is valid JSON, its sources (filesystem paths) and sourcesContent (source contents) are disclosed in the generated source map. Affected code (v8.5.22 — the release carrying the GHSA-6g55 fix) // lib/previous-map.js loadFile(path, cssFile, trusted) { if (!trusted && !this.unsafeMap) { if (!/\.map$/i.test(path)) { return undefined } if (cssFile) { // guard runs ONLY when from is set let relativePath = relative(dirname(cssFile), path) if (relativePath === '..' || relativePath.startsWith('..' + sep) || isAbsolute(relativePath)) { return undefined } } } this.root = dirname(path) if (existsSync(path)) { this.mapFile = path return readFileSync(path, 'utf-8').toString().trim() // sink } } // loadMap(): untrusted annotation path, trusted=false; file === opts.from } else if (this.annotation) { let map = this.annotation if (file) map = join(dirname(file), map) // no from -> map stays the raw URL let unknown = this.loadFile(map, file, false) // file undefined -> cssFile falsy Proof of concept (verified on postcss 8.5.22) const postcss = require('postcss') const fs = require('fs') // a 'secret

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
medium
Published
2026-08-03
Last updated
2026-08-03
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-fxqj-rqcc-2cmp

Exploitation outlook

EPSS (FIRST.org) estimates each CVE’s probability of exploitation in the next 30 days — here is the CSIRTS.com read on those numbers.

Referenced CVEs

CVECSIRTS overviewExternal
CVE-2026-69153coverage & exploitation statusNVD · CVE.org

Same CVEs, other sources

How other CERTs, PSIRTs and databases cover the vulnerabilities in this advisory.

More from GitHub Security Advisories