Skip to content

fix: clone response before setting baseline security headers#509

Merged
ascorbic merged 4 commits intoemdash-cms:mainfrom
mvanhorn:osc/506-immutable-headers
Apr 13, 2026
Merged

fix: clone response before setting baseline security headers#509
ascorbic merged 4 commits intoemdash-cms:mainfrom
mvanhorn:osc/506-immutable-headers

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

What does this PR do?

setBaselineSecurityHeaders in packages/core/src/astro/middleware.ts calls response.headers.set() directly on the Response returned by next(). On Cloudflare, some responses (e.g. /_image/* from Astro's image transform endpoint) have immutable headers, causing TypeError: Can't modify immutable headers.

This PR changes the function to create a new Response with cloned headers before modifying them. The original response body, status, and statusText are preserved. All three call sites in the middleware are updated.

Closes #506

Type of change

  • Bug fix
  • Feature (requires maintainer-approved Discussion)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation and pnpm locale:extract has been run (if applicable)
  • I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/...

AI-generated code disclosure

  • This PR includes AI-generated code

Screenshots / test output

pnpm --silent lint:quick returns 0 diagnostics.

On Cloudflare, some responses (e.g. /_image/* from Astro image transform)
have immutable headers. Cloning into a new Response avoids the TypeError.

Fixes emdash-cms#506
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 13, 2026

🦋 Changeset detected

Latest commit: 3a1eeef

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/admin Patch
@emdash-cms/auth Patch
@emdash-cms/blocks Patch
@emdash-cms/gutenberg-to-portable-text Patch
@emdash-cms/x402 Patch
create-emdash Patch
@emdash-cms/plugin-embeds Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 13, 2026

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/@emdash-cms/admin@509

@emdash-cms/auth

npm i https://pkg.pr.new/@emdash-cms/auth@509

@emdash-cms/blocks

npm i https://pkg.pr.new/@emdash-cms/blocks@509

@emdash-cms/cloudflare

npm i https://pkg.pr.new/@emdash-cms/cloudflare@509

emdash

npm i https://pkg.pr.new/emdash@509

create-emdash

npm i https://pkg.pr.new/create-emdash@509

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/@emdash-cms/gutenberg-to-portable-text@509

@emdash-cms/x402

npm i https://pkg.pr.new/@emdash-cms/x402@509

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/@emdash-cms/plugin-ai-moderation@509

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/@emdash-cms/plugin-atproto@509

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/@emdash-cms/plugin-audit-log@509

@emdash-cms/plugin-color

npm i https://pkg.pr.new/@emdash-cms/plugin-color@509

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/@emdash-cms/plugin-embeds@509

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/@emdash-cms/plugin-forms@509

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/@emdash-cms/plugin-webhook-notifier@509

commit: 3a1eeef

*/
function setBaselineSecurityHeaders(response: Response): void {
function setBaselineSecurityHeaders(response: Response): Response {
const headers = new Headers(response.headers);
Copy link
Copy Markdown
Contributor

@hayatosc hayatosc Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Using the Cache API on Cloudflare Docs , the approach of using response = new Response(response.body, response) is employed to clone a response.
Don't you think this method would be considered better?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call - updated in 3a1eeef to use new Response(response.body, response) per the Cloudflare docs pattern. Cleaner than manually extracting status/statusText.

Use `new Response(response.body, response)` to clone the response
before setting security headers, following the Cloudflare Workers
Cache API pattern. This eliminates manual extraction of status and
statusText properties.
Copy link
Copy Markdown
Collaborator

@ascorbic ascorbic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@ascorbic ascorbic merged commit d56f6c1 into emdash-cms:main Apr 13, 2026
27 checks passed
@emdashbot emdashbot bot mentioned this pull request Apr 13, 2026
fmhall pushed a commit to fmhall/emdash that referenced this pull request Apr 13, 2026
…cms#509)

* fix: clone response before setting baseline security headers

On Cloudflare, some responses (e.g. /_image/* from Astro image transform)
have immutable headers. Cloning into a new Response avoids the TypeError.

Fixes emdash-cms#506

* chore: add changeset for immutable headers fix

* style: format

* refactor: use Cloudflare docs pattern for response cloning

Use `new Response(response.body, response)` to clone the response
before setting security headers, following the Cloudflare Workers
Cache API pattern. This eliminates manual extraction of status and
statusText properties.

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: emdashbot[bot] <emdashbot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EmDash middleware mutates immutable Response headers on Cloudflare/Astro public routes

3 participants