Web Security and WAF · OWASP Top 10 and Common Attacks
CSRF, CORS and Cookie Security
How browsers send credentials, and how to keep cross-site requests safe.
Browsers attach cookies automatically, so a malicious site can trigger state-changing requests to your app (CSRF). Defenses: SameSite=Lax/Strict cookies, anti-CSRF tokens for cookie-authenticated mutations, checking Origin, and never changing state on GET. CORS is a browser mechanism that relaxes the same-origin policy for allowed origins — it doesn't protect your API from non-browser clients and misconfiguration (reflecting any origin with credentials) creates vulnerabilities.
Set-Cookie: session=abc123; Path=/; Secure; HttpOnly; SameSite=Lax
# Safe CORS for a credentialed SPA
Access-Control-Allow-Origin: https://app.example.com (exact match from an allow-list)
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PATCH, DELETE
Vary: Origin
# BUG: Dangerous: echoing any Origin with credentials
Access-Control-Allow-Origin: <whatever the request sent>
Access-Control-Allow-Credentials: true
Common pitfalls
- Disabling CSRF protection for cookie-based APIs.
- Reflecting arbitrary origins with credentials.
- Thinking CORS is an authentication mechanism.
Key points
- Secure, HttpOnly, SameSite cookies
- CSRF tokens for cookie auth
- Strict CORS allow-lists
Further reading: OWASP CSRF Prevention Cheat Sheet
Practice questions
Why doesn't CORS stop attackers from calling your API with curl?
Answer
CORS is enforced by browsers to protect users; servers still receive and process requests from any client, so authentication and authorization are required.
What does SameSite=Lax prevent and what doesn't it cover?
Answer
It stops cookies on most cross-site subrequests and POSTs, blocking typical CSRF; it still sends cookies on top-level GET navigations, so GET must never change state.
Open in the app to mark lessons complete, take notes and track your progress.