You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm running EmDash through the Astro integration (emdash/astro) on Cloudflare Workers and noticed that public, unauthenticated responses include the full Server-Timing header. The finalizeResponse helper in packages/core/src/astro/middleware.ts sets the header unconditionally whenever serverTimings.length > 0.
(This only affects setups that go through the Astro integration — direct API consumers of emdash never hit this middleware.)
Here's an actual response from a public page on my deployment:
This exposes more implementation detail than I'd normally expect to send to an anonymous visitor — that the site is running EmDash, which subsystems are wired up (plugins, sandbox, cron, hooks), and the cold/warm timing profile. There's no opt-out today.
The W3C spec addresses this case directly:
the server can also use relevant logic to control which metrics are returned, when, and to whom — e.g. the server may only provide certain metrics to correctly authenticated users and nothing at all to all others.
— W3C Server-Timing §4 (MDN's Server-Timing page echoes the same)
My first instinct would be to make this opt-in via config — something like a serverTiming field on EmDashConfig, defaulting to off:
emdash({// default: false (no emission)serverTiming: true,// always on// serverTiming: import.meta.env.DEV, // dev / preview only})
But I'm not sure if there was an intentional reason to expose these timings on public responses by default — maybe RUM compatibility, or something I'm missing.
The only place that emits Server-Timing is finalizeResponse, so the implementation should be small. EmDashConfig is shared between the Astro integration and direct API consumers, but the option would only affect the integration path.
This feels related to #674 (Nonce-Based CSP by Default) — same theme of tightening defaults on public responses without changing the admin/dev experience.
In the meantime I'm stripping the header at the Cloudflare Workers fetch entrypoint. Stripping inside Astro middleware doesn't work — finalizeResponse re-applies it after next() returns. It's a workaround, not a fix.
Would you be open to making this opt-in, or is there something I'm missing about why it's on by default?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
I'm running EmDash through the Astro integration (
emdash/astro) on Cloudflare Workers and noticed that public, unauthenticated responses include the fullServer-Timingheader. ThefinalizeResponsehelper inpackages/core/src/astro/middleware.tssets the header unconditionally wheneverserverTimings.length > 0.(This only affects setups that go through the Astro integration — direct API consumers of
emdashnever hit this middleware.)Here's an actual response from a public page on my deployment:
This exposes more implementation detail than I'd normally expect to send to an anonymous visitor — that the site is running EmDash, which subsystems are wired up (plugins, sandbox, cron, hooks), and the cold/warm timing profile. There's no opt-out today.
The W3C spec addresses this case directly:
My first instinct would be to make this opt-in via config — something like a
serverTimingfield onEmDashConfig, defaulting to off:But I'm not sure if there was an intentional reason to expose these timings on public responses by default — maybe RUM compatibility, or something I'm missing.
The only place that emits
Server-TimingisfinalizeResponse, so the implementation should be small.EmDashConfigis shared between the Astro integration and direct API consumers, but the option would only affect the integration path.This feels related to #674 (Nonce-Based CSP by Default) — same theme of tightening defaults on public responses without changing the admin/dev experience.
In the meantime I'm stripping the header at the Cloudflare Workers
fetchentrypoint. Stripping inside Astro middleware doesn't work —finalizeResponsere-applies it afternext()returns. It's a workaround, not a fix.Would you be open to making this opt-in, or is there something I'm missing about why it's on by default?
Beta Was this translation helpful? Give feedback.
All reactions