fix(deps): Update dependency postcss to v8.5.18 [SECURITY] - #91
Conversation
|
Warning Review limit reachedNext included review available in 34 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Team Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
WalkthroughThe frontend ChangesFrontend dependency update
Estimated code review effort: 1 (Trivial) | ~2 minutes Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Dependency ReviewThe following issues were found:
Vulnerabilitiesfrontend/package-lock.json
Only included vulnerabilities with severity moderate or higher. OpenSSF Scorecard
Scanned Files
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@frontend/package.json`:
- Line 47: Update the PostCSS dependency from 8.5.18 to the approved 8.5.23
version in package metadata, then regenerate the lockfile so its resolved
PostCSS entry and integrity data match 8.5.23.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: ee714266-7508-4e67-bcf8-9060cdbd320b
⛔ Files ignored due to path filters (1)
frontend/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (1)
frontend/package.json
| "globals": "^17.0.0", | ||
| "jsdom": "^29.0.0", | ||
| "postcss": "^8.5.6", | ||
| "postcss": "^8.5.18", |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== package files =="
fd -a '^(package|package-lock)\.json$' . 2>/dev/null | sed "s#^$(pwd)/##" | head -50
echo
echo "== frontend/package.json postcss section =="
if [ -f frontend/package.json ]; then
nl -ba frontend/package.json | sed -n '1,80p'
fi
echo
echo "== lockfile postcss entries =="
if [ -f frontend/package-lock.json ]; then
rg -n '"postcss"|source-map' frontend/package-lock.json -C 2 || true
python3 - <<'PY'
import json
p='frontend/package-lock.json'
data=json.load(open(p))
packages=data.get('packages', {})
for pkg in [p for p in packages if p.endswith('node_modules/postcss') or p=='node_modules/postcss']:
print(pkg, '=>', packages[pkg])
PY
fi
echo
echo "== npmjs/release metadata =="
npm view postcss version dist-tags --json 2>/dev/null | sed -n '1,120p' || trueRepository: ByronWilliamsCPA/rag-processor
Length of output: 323
🌐 Web query:
PostCSS 8.5.23 source-map security hardening release notes
💡 Result:
PostCSS version 8.5.23, released on July 24, 2026, includes security hardening related to source map handling [1][2]. Specifically, this release introduces a change to prevent the loading of source map files when the 'from' option is not provided [3][2]. This change is part of ongoing efforts to address security vulnerabilities involving arbitrary file read and information disclosure via attacker-controlled 'sourceMappingURL' comments in CSS [4][5][6]. Previous versions of PostCSS would attempt to dereference and load these paths from the local filesystem by default, even when no source map was intended or explicitly configured, potentially allowing attackers to read files on the host system [4][5][6]. By requiring the 'from' option to be present for source map loading, PostCSS adds a layer of defense to limit the scenarios in which files are automatically accessed [3][2].
Citations:
- 1: postcss/postcss@eb9e1fe
- 2: https://github.com/postcss/postcss/blob/main/CHANGELOG.md
- 3: postcss/postcss@8.5.22...8.5.23
- 4: GHSA-6g55-p6wh-862q
- 5: https://osv.dev/vulnerability/GHSA-6g55-p6wh-862q
- 6: https://psirt.com/advisory/GHSA-r28c-9q8g-f849
🌐 Web query:
PostCSS 8.5.25 GitHub release
💡 Result:
PostCSS version 8.5.25 was released on July 29, 2026 [1][2][3][4]. This release included two specific fixes: a correction for an 8.5.17 visitor regression and a fix for list.split when handling non-string values [1].
Citations:
- 1: https://tleapps.com/version/postcss/postcss-8-5-25/
- 2: https://github.com/postcss/postcss/releases
- 3: https://www.npmjs.com/package/postcss
- 4: https://security.snyk.io/package/npm/postcss
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== npm metadata =="
npm view postcss version dist-tags --json 2>/dev/null || true
echo
echo "== frontend/package.json =="
python3 - <<'PY'
from pathlib import Path
p = Path("frontend/package.json")
text = p.read_text()
for i, line in enumerate(text.splitlines(), 1):
if "postcss" in line.lower() or i <= 80:
print(f"{i}: {line}")
PY
echo
echo "== frontend/package-lock.json postcss entries =="
python3 - <<'PY'
import json
from pathlib import Path
p = Path("frontend/package-lock.json")
data = json.loads(p.read_text())
for name, entry in data.get("packages", {}).items():
if name == "node_modules/postcss" or name.endswith("/node_modules/postcss"):
print(f"{name}:")
for k, v in entry.items():
if k in ("version", "resolved", "integrity", "dependencies", "dev"):
print(f" {k}: {v}")
PY
echo
echo "== semantic comparison =="
python3 - <<'PY'
import re
locked = Path("frontend/package-lock.json").read_text()
m = re.search(r'"node_modules/postcss":\s*\{[^"]*"version"\s*:\s*"([^"]+)"', locked)
manifest = Path("frontend/package.json").read_text()
match = re.search(r'"postcss"\s*:\s*"([^"]+)"', manifest)
print(f"locked_version={m.group(1) if m else None}")
print(f"manifest_range={match.group(1) if match else None}")
PYRepository: ByronWilliamsCPA/rag-processor
Length of output: 2703
Update the locked PostCSS version.
frontend/package-lock.json pins PostCSS to 8.5.18, so installs from the lockfile do not get PostCSS 8.5.23 source-map hardening. Regenerate the lockfile to resolve PostCSS to the latest approved patch version.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@frontend/package.json` at line 47, Update the PostCSS dependency from 8.5.18
to the approved 8.5.23 version in package metadata, then regenerate the lockfile
so its resolved PostCSS entry and integrity data match 8.5.23.
There was a problem hiding this comment.
Pull request overview
Updates the frontend build tooling dependency postcss to a patched version that includes security fixes, aligning with the Renovate-driven dependency maintenance workflow.
Changes:
- Bumped
postcssinfrontend/package.jsonto^8.5.18. - Updated the
node_modules/postcssentry infrontend/package-lock.jsonto8.5.18with corresponding resolved URL and integrity hash.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| frontend/package.json | Updates the declared devDependency range for postcss to ^8.5.18. |
| frontend/package-lock.json | Updates the locked postcss package version metadata to 8.5.18. |
Files not reviewed (1)
- frontend/package-lock.json: Generated file
| "globals": "^17.0.0", | ||
| "jsdom": "^29.0.0", | ||
| "postcss": "^8.5.6", | ||
| "postcss": "^8.5.18", |
|
9f80a0c to
d129cdf
Compare
d129cdf to
952082b
Compare
|



Summary
Why
Scheduled patch update, bug fixes and security patches with no API changes.
Changes
This PR contains the following updates:
8.5.15→8.5.18Warning
Some dependencies could not be looked up. Check the Dependency Dashboard for more information.
Impact
Acceptance Criteria
Testing
Notes
PostCSS: Path Traversal in Previous Source Map Auto-Loading (sourceMappingURL) leads to Arbitrary .map File Disclosure
GHSA-r28c-9q8g-f849
More information
Details
Vulnerability Details
File:
lib/previous-map.jsLine: 87-98 (
loadFile), 129-144 (loadMap)Root Cause
PostCSS auto-detects a
/*# sourceMappingURL=... */comment inside the CSS text it is asked to parse and, unless the caller explicitly passesmap: false, attempts to load that path from disk as a "previous source map." This happens on everypostcss.parse()/postcss().process()call by default (opt-out, not opt-in).loadMap()builds the candidate path viajoin(dirname(opts.from), annotation), whereannotationis the raw, attacker-controlled string from the CSS comment.path.join()normalizes but does not sandbox..segments, so a../../../prefix walks the resolved path outside the intended directory. Ifopts.fromis not set at all, the annotation is used completely unmodified — an absolute path in the CSS comment is read verbatim.8.5.12 already fixed a strictly worse variant of this (any file, any extension, could be read) by requiring the resolved path to end in
.map(loadFile()). That fix did not address the traversal itself, only the target extension. Since thejoin(dirname(file), map)logic has existed unchanged since PostCSS 8.0.0 (Feb 2020), any file ending in.mapremains readable through this path in the current release (8.5.16).Once loaded,
MapGenerator.isMap()treats the mere presence of a loaded "previous map" as an implicit request to generateresult.map, even when the caller never set themapoption. If the loaded map has asourcesContentfield (common for maps emitted by bundlers/transpilers), that content is merged intoresult.mapand returned to the caller — disclosing the traversed-to file's content to whoever supplied the CSS.Attack Scenario
postcss().process(userCss, { from: '/app/uploads/user123/input.css', to: '/app/uploads/user123/output.css' })— idiomatic usage;mapoption untouched./*# sourceMappingURL=../../../../some/other/app/dist/bundle.js.map */(or an absolute path iffromis unset)..mapfile and folds itssourcesContentintoresult.map.result.map— writes it next to the CSS output or returns it via API (source maps are meant to be consumed by browser devtools, so this is commonly public/served).Impact
Disclosure of the contents of arbitrary
.mapfiles reachable via path traversal (or absolute path whenfromis unset) from the process's filesystem. Affects any application processing CSS it does not fully trust without explicitly passingmap: false. No authentication or user interaction beyond submitting CSS text is required.Vulnerable Code
Recommended Fix
Constrain the resolved path to remain inside the CSS file's own directory instead of relying solely on a filename-extension check:
I've implemented, tested (full existing test suite — 660/660 passing, plus new PoC-based regression checks for both the traversal and legitimate same-directory cases), and can share this fix on request or via a private fork if invited.
Verification
Dynamically confirmed on v8.5.16 (current npm release / repo HEAD) via a standalone Node.js harness against
lib/postcss.js: a "secret".mapfile placed two directories outside a simulated project directory was read via a craftedsourceMappingURLcomment in otherwise-innocuous CSS, with itssourcesContentappearing verbatim inresult.map.toString()— with nomapoption set by the caller. A second harness confirmed the simpler no-fromcase reads an absolute path directly. A third harness confirmedmap: falseis the only current workaround. The attached fix branch closes both vectors while keeping all 660 existing unit tests green.Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
postcss/postcss (postcss)
v8.5.18Compare Source
opts.fromfolder for security reasons (useunsafeMap: trueto disable the check).v8.5.17Compare Source
Maximum call stack size exceedederror.postcss.fromJSON().Input#origin()for unmapped end position (by @chatman-media).v8.5.16Compare Source
Input#origin()position (by @mizdra).rawsafter rehydrating a JSON AST (by @sarathfrancis90).nodesof new node (by @MahinAnowar).offsetinpositionBy()(by @greymoth-jp).rangeBy()onindex: 0(by @sarathfrancis90).Configuration
📅 Schedule: (in timezone America/New_York)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR has been generated by Mend Renovate.