Where the configuration lives
Cloudflare Pages reads a plain-text _headers file from the build output and
applies the rules it defines per matched path. Nomadrex.dev's file defines a site-wide rule for
/*, plus narrower rules for /account/* and /assets/* that
override or extend the defaults for those specific paths.
The site-wide Content-Security-Policy
The Content-Security-Policy header restricts what a page is allowed to load or
execute, directive by directive:
default-src 'self'— anything not covered by a more specific directive is restricted to the site's own origin.script-src— allows only the site's own scripts, a specific script hash (rather than a blanket'unsafe-inline', which would allow any inline script), and named third-party domains for Cloudflare's analytics beacon and Google's ad-serving scripts.connect-src— restricts what origins scripts can call over fetch/XHR, explicitly listing the Supabase project, the shared visitor-counter API, Cloudflare's analytics endpoint, and Google's ad-quality endpoint.frame-src— allows only the specific origins needed for embedded content (YouTube's privacy-enhanced embed domain and Google's ad iframes).frame-ancestors 'none'combined withX-Frame-Options: DENY— prevents the site from being embedded in a frame on another site, which mitigates clickjacking.object-src 'none'— disallows plugin content like Flash or legacy embeds entirely.upgrade-insecure-requests— instructs the browser to upgrade any accidental HTTP sub-resource requests to HTTPS.
Deliberately not present: a blanket 'unsafe-inline' in script-src. Any
inline script must instead match an explicit hash listed in the policy, which means an attacker
who manages to inject a different inline script (for example, through a content injection bug)
cannot get it to execute, because it won't match the allowed hash.
Supporting headers
Permissions-Policy: camera=(), geolocation=(), microphone=()— explicitly disables browser APIs the site has no legitimate use for, so they can't be invoked even by a compromised third-party script.Referrer-Policy: strict-origin-when-cross-origin— limits how much of the current URL is leaked to other sites via the Referer header.X-Content-Type-Options: nosniff— stops browsers from guessing a different MIME type than the one the server declared, which closes off a class of content-sniffing attacks.
Path-specific overrides
The /account/* path adds Cache-Control: private, no-store, max-age=0
and a stricter Referrer-Policy: no-referrer, because account pages can contain
session-specific content that should never be cached by a shared cache or leaked via referrer
to an external link. The /assets/* path instead sets a long, immutable cache
lifetime, since built asset filenames change when their content changes, so aggressive caching
is safe there.
Why this is tested, not just configured
A header file is only useful if it stays correct as the site changes. This site's automated
test suite asserts directly against the shipped _headers file — for example,
confirming the script hash and third-party script domains are present and that
'unsafe-inline' never appears in script-src — so a future change that
accidentally weakens the policy fails a test instead of shipping quietly.
Related reading: Testing a small static site and How Cloudflare Pages and Workers fit together.