Ambient Authority
“Ambient auth” means credentials the browser attaches automatically — cookies, HTTP Basic, NTLM, client certs. It’s what makes CSRF possible: the victim’s browser includes them on cross-site requests without asking.
Recognise + defuse ambient auth
EXAMPLE
// THE PROBLEM — cookie auth is ambient
GET /api/transfer HTTP/1.1
Cookie: sid=abc123 ← browser attaches this on every request,
even from attacker.com
// THREE GENERATIONS OF DEFENCE
// 1) The PASSIVE defence — SameSite cookies (browser-level)
Set-Cookie: sid=…; HttpOnly; Secure; SameSite=Lax
// Lax — browser DOESN'T send the cookie on cross-site POST.
// Strict — browser doesn't send the cookie on ANY cross-site request.
// None — old behaviour (requires Secure). Avoid.
// 2) The ACTIVE defence — anti-CSRF token (server-level)
Set-Cookie: csrf=<random>; SameSite=Strict
// Client mirrors it back in a header
fetch('/api/transfer', {
method: 'POST',
headers: { 'X-CSRF-Token': document.cookie.match(/csrf=([^;]+)/)?.[1] },
});
// Server compares cookie value with header value — attacker page can't read the cookie cross-site.
// 3) The HYBRID defence — non-simple request type forces a CORS preflight
fetch('/api/transfer', {
method: 'POST',
headers: { 'Content-Type': 'application/json' }, // 'non-simple' → preflighted
body: JSON.stringify(payload),
});
// Browsers refuse to preflight to an origin that hasn't allowed yours. Attackers can't.
// 4) STOP USING ambient auth where you can
// SPA + bearer token (NOT in localStorage, NOT in cookies):
const { accessToken } = await fetch('/login', { credentials: 'include' }).then(r => r.json());
let token = accessToken; // in-memory; refreshed via httpOnly cookie
fetch('/api/anything', {
headers: { Authorization: `Bearer ${token}` }, // explicit — not ambient
});
// Production CSRF defence is LAYERED:
// • SameSite=Lax cookies (kills 90% of CSRF without changing app code)
// • Custom-header / token check on every mutating endpoint (defence in depth)
// • Origin / Referer check on top of both (the third layer)
Why it matters
CSRF and XSS form a security tradeoff. Cookie auth needs CSRF defences; bearer auth needs XSS defences. Pick the model deliberately and document why — mixing both gives you the worst of each.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// The root cause: "ambient" credentials. // Cookies, HTTP Basic, NTLM, client certs — all auto-sent by the browser. // CSRF defences add a credential the attacker page CANNOT forge.Try it Yourself »
Discussion
Loading…