Skip to content

🚨 [security] Update @astrojs/cloudflare 13.7.0 → 14.1.3 (major) - #471

Open
depfu[bot] wants to merge 1 commit into
mainfrom
depfu/update/npm/@astrojs/cloudflare-14.1.3
Open

🚨 [security] Update @astrojs/cloudflare 13.7.0 → 14.1.3 (major)#471
depfu[bot] wants to merge 1 commit into
mainfrom
depfu/update/npm/@astrojs/cloudflare-14.1.3

Conversation

@depfu

@depfu depfu Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

🚨 Your current dependencies have known security vulnerabilities 🚨

This dependency update fixes known security vulnerabilities. Please see the details below and assess their impact carefully. We recommend to merge and deploy this as soon as possible!


Here is everything you need to know about this upgrade. Please take a good look at what changed and the test results before merging this pull request.

What changed?

✳️ @​astrojs/cloudflare (13.7.0 → 14.1.3) · Repo · Changelog

↗️ @​emnapi/runtime (indirect, 1.10.0 → 1.11.1) · Repo

Release Notes

1.11.1

What's Changed

  • fix: refresh stale shared memory buffer before atomic access (v1.x backport) by @Brooooooklyn in #218

New Contributors

Full Changelog: v1.11.0...v1.11.1

1.11.0

What's Changed

  • feat: add napi_create_external_sharedarraybuffer (#211)
  • feat: support SharedArrayBuffer in napi_create_typedarray (#212)
  • refactor: remove use of PThread.runningWorkers (#216)

Full Changelog: v1.10.0...v1.11.0

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 8 commits:

↗️ nanoid (indirect, 3.3.12 → 3.3.16) · Repo · Changelog

Commits

See the full diff on Github. The new version differs by 13 commits:

↗️ postcss (indirect, 8.5.14 → 8.5.24) · Repo · Changelog

Security Advisories 🚨

🚨 PostCSS: Path Traversal in Previous Source Map Auto-Loading (sourceMappingURL) leads to Arbitrary .map File Disclosure

Vulnerability Details

File: lib/previous-map.js
Line: 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 passes map: false, attempts to load that path from disk as a "previous source map." This happens on every postcss.parse() / postcss().process() call by default (opt-out, not opt-in).

loadMap() builds the candidate path via join(dirname(opts.from), annotation), where annotation is 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. If opts.from is 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 the join(dirname(file), map) logic has existed unchanged since PostCSS 8.0.0 (Feb 2020), any file ending in .map remains 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 generate result.map, even when the caller never set the map option. If the loaded map has a sourcesContent field (common for maps emitted by bundlers/transpilers), that content is merged into result.map and returned to the caller — disclosing the traversed-to file's content to whoever supplied the CSS.

Attack Scenario

  1. A service accepts user-submitted CSS and runs it through PostCSS to lint/format/transform it, e.g. postcss().process(userCss, { from: '/app/uploads/user123/input.css', to: '/app/uploads/user123/output.css' }) — idiomatic usage; map option untouched.
  2. Attacker submits CSS containing /*# sourceMappingURL=../../../../some/other/app/dist/bundle.js.map */ (or an absolute path if from is unset).
  3. PostCSS reads that .map file and folds its sourcesContent into result.map.
  4. The service does what most build pipelines do with a truthy 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).
  5. Attacker retrieves the emitted map and reads out the traversed file's content.

Impact

Disclosure of the contents of arbitrary .map files reachable via path traversal (or absolute path when from is unset) from the process's filesystem. Affects any application processing CSS it does not fully trust without explicitly passing map: false. No authentication or user interaction beyond submitting CSS text is required.

Vulnerable Code

loadFile(path, cssFile, trusted) {
  if (!trusted && !this.unsafeMap) {
    if (!/\.map$/i.test(path)) {
      return undefined
    }
  }
  this.root = dirname(path)
  if (existsSync(path)) {
    this.mapFile = path
    return readFileSync(path, 'utf-8').toString().trim()
  }
}

loadMap(file, prev) {
...
} else if (this.annotation) {
let map = this.annotation
if (file) map = join(dirname(file), map)
let unknown = this.loadFile(map, file, false)
...
}
}

Recommended Fix

Constrain the resolved path to remain inside the CSS file's own directory instead of relying solely on a filename-extension check:

loadFile(path, cssFile, trusted) {
  if (!trusted && !this.unsafeMap) {
    if (!/\.map$/i.test(path)) {
      return undefined
    }
    if (!cssFile) return undefined
    let root = resolve(dirname(cssFile))
    let resolvedPath = resolve(root, path)
    if (resolvedPath !== root && !resolvedPath.startsWith(root + sep)) {
      return undefined
    }
  }
  this.root = dirname(path)
  if (existsSync(path)) {
    this.mapFile = path
    return readFileSync(path, 'utf-8').toString().trim()
  }
}

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" .map file placed two directories outside a simulated project directory was read via a crafted sourceMappingURL comment in otherwise-innocuous CSS, with its sourcesContent appearing verbatim in result.map.toString() — with no map option set by the caller. A second harness confirmed the simpler no-from case reads an absolute path directly. A third harness confirmed map: false is the only current workaround. The attached fix branch closes both vectors while keeping all 660 existing unit tests green.

Release Notes

8.5.23

  • Do not load source map without opts.from for security reasons.

8.5.22

  • Fixed custom property losing semicolon before a comment (by @sarathfrancis90).

8.5.21

8.5.20

8.5.19

  • Fixed cleaning before for new nodes inserted to Root (by @MahinAnowar).

8.5.18

  • Restricted loading previous source maps file to the opts.from folder for security reasons (use unsafeMap: true to disable the check).

8.5.17

  • Fixed Maximum call stack size exceeded error.
  • Fixed Prototype hijacking for postcss.fromJSON().
  • Fixed Input#origin() for unmapped end position (by @chatman-media).

8.5.16

8.5.15

  • Fixed declaration parsing performance (by @homanp).

Does any of this look wrong? Please let us know.

Commits

See the full diff on Github. The new version differs by 74 commits:

🆕 @​emnapi/core (added, 1.11.1)

🆕 @​emnapi/wasi-threads (added, 1.2.2)

🆕 @​napi-rs/wasm-runtime (added, 1.2.0)

🆕 @​oxc-project/types (added, 0.139.0)

🆕 @​rolldown/binding-android-arm64 (added, 1.1.5)

🆕 @​rolldown/binding-darwin-arm64 (added, 1.1.5)

🆕 @​rolldown/binding-darwin-x64 (added, 1.1.5)

🆕 @​rolldown/binding-freebsd-x64 (added, 1.1.5)

🆕 @​rolldown/binding-linux-arm-gnueabihf (added, 1.1.5)

🆕 @​rolldown/binding-linux-arm64-gnu (added, 1.1.5)

🆕 @​rolldown/binding-linux-arm64-musl (added, 1.1.5)

🆕 @​rolldown/binding-linux-ppc64-gnu (added, 1.1.5)

🆕 @​rolldown/binding-linux-s390x-gnu (added, 1.1.5)

🆕 @​rolldown/binding-linux-x64-gnu (added, 1.1.5)

🆕 @​rolldown/binding-linux-x64-musl (added, 1.1.5)

🆕 @​rolldown/binding-openharmony-arm64 (added, 1.1.5)

🆕 @​rolldown/binding-wasm32-wasi (added, 1.1.5)

🆕 @​rolldown/binding-win32-arm64-msvc (added, 1.1.5)

🆕 @​rolldown/binding-win32-x64-msvc (added, 1.1.5)

🆕 @​rolldown/pluginutils (added, 1.0.1)

🆕 @​tybys/wasm-util (added, 0.10.3)

🆕 lightningcss (added, 1.33.0)

🆕 lightningcss-android-arm64 (added, 1.33.0)

🆕 lightningcss-darwin-arm64 (added, 1.33.0)

🆕 lightningcss-darwin-x64 (added, 1.33.0)

🆕 lightningcss-freebsd-x64 (added, 1.33.0)

🆕 lightningcss-linux-arm-gnueabihf (added, 1.33.0)

🆕 lightningcss-linux-arm64-gnu (added, 1.33.0)

🆕 lightningcss-linux-arm64-musl (added, 1.33.0)

🆕 lightningcss-linux-x64-gnu (added, 1.33.0)

🆕 lightningcss-linux-x64-musl (added, 1.33.0)

🆕 lightningcss-win32-arm64-msvc (added, 1.33.0)

🆕 lightningcss-win32-x64-msvc (added, 1.33.0)

🆕 rolldown (added, 1.1.5)

🆕 @​astrojs/internal-helpers (added, 0.10.1)

🆕 picomatch (added, 4.0.5)

🆕 tinyglobby (added, 0.2.17)

🆕 vite (added, 8.1.5)


Depfu Status

Depfu will automatically keep this PR conflict-free, as long as you don't add any commits to this branch yourself. You can also trigger a rebase manually by commenting with @depfu rebase.

All Depfu comment commands
@​depfu rebase
Rebases against your default branch and redoes this update
@​depfu recreate
Recreates this PR, overwriting any edits that you've made to it
@​depfu merge
Merges this PR once your tests are passing and conflicts are resolved
@​depfu cancel merge
Cancels automatic merging of this PR
@​depfu close
Closes this PR and deletes the branch
@​depfu reopen
Restores the branch and reopens this PR (if it's closed)
@​depfu pause
Ignores all future updates for this dependency and closes this PR
@​depfu pause [minor|major]
Ignores all future minor/major updates for this dependency and closes this PR
@​depfu resume
Future versions of this dependency will create PRs again (leaves this PR as is)

@depfu depfu Bot added the depfu label Jul 15, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 15, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
head-start c23984a Jul 28 2026, 09:55 AM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 15, 2026

Copy link
Copy Markdown

Deploying head-start with  Cloudflare Pages  Cloudflare Pages

Latest commit: 53af908
Status:🚫  Build failed.

View logs

@depfu
depfu Bot force-pushed the depfu/update/npm/@astrojs/cloudflare-14.1.3 branch from d2d24f2 to 53af908 Compare July 17, 2026 10:35
@depfu
depfu Bot force-pushed the depfu/update/npm/@astrojs/cloudflare-14.1.3 branch from 53af908 to c23984a Compare July 28, 2026 09:50
@depfu depfu Bot changed the title 🚨 [security] Update @astrojs/cloudflare 12.6.13 → 14.1.3 (major) 🚨 [security] Update @astrojs/cloudflare 13.7.0 → 14.1.3 (major) Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants