Lion Cipher Lab
Block cross-site attacks with a Fetch Metadata resource isolation policy (Sec-Fetch-* headers)
- AppSec / DevSecOps
- Intermediate
- ~60 min
- Free · no account required
Why it matters
Several of the web's nastiest bug classes share one shape: some other website makes YOUR browser send a request to a site you are logged into, and the browser helpfully attaches your cookies. A hidden form forges a money transfer (CSRF). A script tag pulls in a JavaScript file that contains your API key (XSSI, cross-site script inclusion). An invisible image or a timed request tells the other site whether you are logged in, or what is in your account (XS-Leaks, cross-site leaks). Each has its own classic fix, and teams forget one. Modern browsers now label every request with Fetch Metadata…
What you'll learn
- reading the four Fetch Metadata request headers (Sec-Fetch-Site, Sec-Fetch-Mode, Sec-Fetch-Dest, Sec-Fetch-User) and saying in plain words what each one tells the server about where a request came from and what it is for
- writing a server-side Resource Isolation Policy that refuses cross-site requests which are not top-level navigations, in about twenty lines of standard-library Python
- building a request-matrix harness that replays legit flows and cross-site attacks side by side and counts attacks stopped versus legit flows broken
- rolling a policy out safely: report-only logging first, then enforcement, with an allowlist for endpoints that must stay cross-site (public assets, SSO callbacks, webhooks)
- telling same-site from same-origin and deciding per endpoint whether a sibling subdomain deserves trust
- choosing a fallback for browsers and clients that send no Sec-Fetch-* headers, and explaining why this policy is defense in depth rather than your only CSRF defense
- adding the right Vary header so caches never serve a blocked or allowed response to the wrong kind of request
Steps in this lab
- The problem in one breath: other websites can make your browser send requests
- Meet the four Sec-Fetch-* headers
- Set up a folder and check Python
- Build the toy bank, with the policy already inside it
- Build the request-matrix harness (and be honest about what it simulates)
- BEFORE: run it with no policy
- Report-only first: see what you would block before you block it
- The tempting one-liner, measured: 'just block cross-site'
- AFTER: the baseline policy, and the four attacks it lets through
- Same-site is not same-origin: decide per endpoint how far to trust your siblings
- Hardened: three more rules, measured, and the one attack left standing
- Tell caches the answer depends on the headers (Vary)
- When it does NOT protect you, and what to pair it with
- Optional: see the real headers in your own browser (DevTools)
- What you measured, and the reflex to keep