Aug 3, 2026·5 min read·112 visits
PostCSS fails to validate sourceMappingURL paths when the 'from' option is omitted, allowing unauthenticated attackers to read arbitrary local .map files.
A directory traversal and arbitrary file read vulnerability exists in PostCSS due to an incomplete fix of CVE-2026-45623. When parsing a CSS file containing a sourceMappingURL comment with the 'from' parameter unset, path traversal and absolute path validations are bypassed, enabling attackers to read arbitrary local .map files.
PostCSS is a widely used Node.js library that parses and transforms CSS styles using JavaScript plugins. To support developers debugging compiled CSS, PostCSS incorporates functionality to resolve and load upstream source maps specified via the sourceMappingURL comment. This capability exposes an attack surface where an attacker-controlled CSS file can point to local filesystem resources.
The vulnerability classified as CVE-2026-69153 represents an incomplete fix for a prior directory traversal issue tracked under CVE-2026-45623. Under specific API execution conditions, PostCSS fails to apply path resolution restrictions to the target map file. This allows attackers to bypass directory boundaries and access arbitrary files on the local file system.
The vulnerability is triggerable when the library parses untrusted style input without an explicitly defined source path. This scenario is common in server-side CSS preprocessors, template compilation engines, and online CSS formatter applications.
The root cause of CVE-2026-69153 lies in the conditional check logic within the loadFile method of the PreviousMap class, implemented in lib/previous-map.js. The previous validation fix aimed to prevent directory traversal by restricting the path to resources ending in .map and checking that the relative path did not escape the base directory using parent sequences (..).
However, this path traversal check was nested inside a conditional block checking for the presence of the cssFile parameter. If an application executes PostCSS without passing the from option (which defines the input CSS file path), the cssFile parameter resolves to undefined. Consequently, the code skips the traversal validation block entirely.
Because the path validation is bypassed when cssFile is falsy, the application proceeds to resolve the target path directly. The parser uses the Node.js file system API to verify file existence and read the content. Any local JSON file ending with the .map extension, or any file that can be parsed as a map, is then loaded into memory.
The vulnerability can be analyzed by comparing the logic before and after the security patch. In the vulnerable implementation, the boundary validation is wrapped inside the if (cssFile) block, allowing unvalidated execution if the file source is unspecified.
// Vulnerable Implementation in lib/previous-map.js
loadFile(path, cssFile, trusted) {
if (!trusted && !this.unsafeMap) {
if (!/\.map$/i.test(path)) {
return undefined;
}
// Validation is conditionally bypassed if cssFile is undefined
if (cssFile) {
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
// Arbitrary file read occurs here
return readFileSync(path, 'utf-8').trim()
}
}The patch refactors this logic by establishing a fail-secure approach. It moves the cssFile check to the top of the validation phase. If the cssFile is missing when processing untrusted maps, the operation returns undefined immediately, neutralizing the bypass.
// Patched Implementation in lib/previous-map.js
loadFile(path, cssFile, trusted) {
if (!trusted && !this.unsafeMap) {
if (!/\.map$/i.test(path)) return undefined
// Immediately fail if the source CSS file context is missing
if (!cssFile) return undefined
let rel = relative(dirname(cssFile), path)
if (rel === '..' || rel.startsWith('..' + sep) || isAbsolute(rel)) {
return undefined
}
}
this.root = dirname(path)
if (existsSync(path)) {
this.mapFile = path
return readFileSync(path, 'utf-8').trim()
}
}Exploitation of CVE-2026-69153 requires the target application to process user-supplied CSS payloads without setting the from property. An attacker exploits this by injecting a malicious CSS comment referencing a target file.
The payload consists of normal CSS declarations followed by a specialized comment pattern. The comment utilizes directory traversal sequences to target sensitive system files. For example, to read a configuration map outside of the expected directory, the attacker supplies the following syntax:
body { color: red; }
/*# sourceMappingURL=../../../../etc/app-config.map */When the server-side application processes this payload, PostCSS evaluates the sourceMappingURL. Since from is not configured, the validation is skipped, and the server-side process reads /etc/app-config.map from disk. If the file is a valid JSON document, its properties are loaded into the generated output map, leaking sensitive configuration data or environment variables back to the attacker.
The security impact of CVE-2026-69153 is classified as Medium, with a CVSS v4.0 score of 6.3. The vulnerability primarily affects confidentiality, allowing unauthorized read access to files on the server's local file system.
The scope of the file read is limited to files that pass the .map file extension check or files that can be parsed as JSON. However, developers often store critical data, build assets, environment variables, or API keys in .map files during build processes. Additionally, on certain operating systems or configurations, symbolic links or directory paths may be manipulated to point other configuration files to a .map extension.
No integrity or availability impact is associated with this vulnerability. An attacker cannot write files, modify system states, or easily trigger a denial of service. However, the exposure of credentials or application secrets can be utilized to execute subsequent attacks against the target network or backend services.
The primary remediation for this vulnerability is upgrading PostCSS to a non-vulnerable version. Organizations should update dependencies to version 8.5.19 or 8.5.23 depending on their specific package branch requirements.
For environments where immediate patching is not feasible, developers can mitigate the flaw by ensuring the from property is always configured when invoking the PostCSS API. Specifying a static, sandboxed input file path ensures that path traversal checks are enforced.
// Mitigation by configuring the 'from' parameter
postcss([plugin]).process(untrustedCSS, { from: 'sandbox/input.css' });Additionally, implementing a Web Application Firewall (WAF) rule to block CSS submissions containing sourceMappingURL sequences targeting local files or containing directory traversal signatures can reduce the attack surface.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
postcss PostCSS | < 8.5.19 | 8.5.19 |
postcss PostCSS | >= 8.5.20 < 8.5.23 | 8.5.23 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Network |
| CVSS v4.0 | 6.3 |
| Impact | Confidentiality (Partial File Disclosure) |
| Exploit Status | Proof of Concept |
| KEV Status | Not Listed |
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')
A critical security vulnerability has been identified and patched in the WebUI component of pyLoad, a popular Python-based open-source download manager. This vulnerability allows attackers to completely bypass API rate limits and spoof client IP addresses in audit logs due to unsafe parsing of the X-Forwarded-For HTTP header.
An authorization bypass and credential oracle vulnerability in pyload-ng allows authenticated users with minimal or no privileges to brute-force the administrator password. This is achieved through sensitive API methods exposed globally combined with a non-constant-time password hash comparison algorithm.
An authentication bypass vulnerability in pyLoad allows unauthenticated remote attackers to gain administrative API access. The vulnerability is caused by a logical flaw in the API key cache validation lookup, where authentication states are cached using only the public key identifier, skipping cryptographic token verification on cache hits.
An authorization bypass vulnerability in Strawberry GraphQL between versions 0.217.0 and 0.326.1 occurs when a synchronous permission handler returns an awaitable object (such as an unawaited coroutine). Due to Python's truthiness rules, the unawaited coroutine is evaluated as True, leading to an immediate bypass of security policies.
An uncontrolled resource consumption vulnerability in Strawberry GraphQL allows unauthenticated remote attackers to trigger a Denial of Service on persistent WebSocket connections using the legacy graphql-ws protocol. When the server enforces max_subscriptions_per_connection, naturally terminating subscriptions are not cleared from memory registries, leading to exhaustion of connection slots.
A high-severity type-confusion vulnerability exists in NearForm fast-jwt prior to version 6.3.0. The vulnerability allows attackers to bypass crucial claim validation steps (such as expiration, issuer, audience, and subject validations) by presenting a validly signed JSON Web Token structured as a JSON array instead of a JSON object. This occurs because the library's decoder fails to reject JSON arrays during type evaluation.