核心 · Key Idea
In one line: a cookie is data the browser auto-attaches to requests; CORS is the browser's policy on cross-origin requests; CSRF is an attack exploiting that auto-attach behavior. Get the three sorted — 90 % of web-security bugs go away.
Cookie#
Set-Cookie: session=abc; Domain=.example.com; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600Domain / PathScope
Decides which requests carry the cookie.
HttpOnlyJS-unreadable
JS can't read it → defeats XSS session theft.
SecureHTTPS-only
Only sent on https requests.
SameSiteSame-site policy
Strict / Lax (default) / None — controls whether cross-site requests carry it. **SameSite=Lax is the modern first-line CSRF defense**.
__Host-Prefix
Forces Secure + Path=/ + no Domain — the strictest cookie class.
CORS (Cross-Origin Resource Sharing)#
CORS is a browser-side policy — by default JS can't read cross-origin responses. The server must explicitly allow it via response headers.
# Simple request
GET /api Origin: https://app.com
→ Access-Control-Allow-Origin: https://app.com
# Complex requests first issue an OPTIONS preflight
OPTIONS /api Origin: https://app.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Auth
→ Access-Control-Allow-Origin: https://app.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Auth
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 600Key insight: CORS doesn't protect the server — the browser protects the user. Your backend curling itself never needs CORS headers.
CSRF (Cross-Site Request Forgery)#
Classic scenario:
You're logged into bank.com with a live cookie
→ You open evil.com which contains <img src="https://bank.com/transfer?to=eve&amount=1000">
→ Browser auto-attaches the bank.com cookie
→ Bank executes the transfer (if undefended)
Defenses (modern priority order):
SameSite=Lax/Strictcookies — cross-site requests don't carry the cookie. Cuts the attack at the root.- CSRF tokens — server embeds a one-shot token; the cross-site attacker can't read it.
- Double-submit cookie — match a header against a cookie; stateless on the server.
- Check Origin / Referer as a fallback.
- Never accept state-changing GETs — GET should never modify state.
How they relate#
Practical notes#
- Use HttpOnly + Secure + SameSite=Lax cookies for sessions. Don't put tokens in localStorage — XSS = account compromise.
- Common CORS gotcha:
Allow-Origin: *+Allow-Credentials: true— browsers reject this. With credentials you must specify the origin. - OPTIONS preflight failure = CORS error — DevTools shows exactly which header is missing or the origin mismatch.
- Cookie sharing across subdomains: when
api.example.comandwww.example.comshare.example.com, setDomain=.example.comexplicitly. - Cross-domain SSO must use OAuth / SAML, not cookies.
- API for native apps / server-to-server: doesn't go through a browser → CORS / CSRF don't apply, but you still need authentication (API key / OAuth / mTLS).
Easy confusions#
CORS
Browser **proactively limits** cross-origin response reads.
Concerns "can I read the data".
Concerns "can I read the data".
CSRF
Attacker **abuses** auto-cookie behavior.
Concerns "will I be impersonated into submitting".
Concerns "will I be impersonated into submitting".