Web Security Vulnerabilities: XSS, CSRF, CORS & Security Headers
Protecting Python web applications requires understanding core browser security mechanisms and vulnerabilities: Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), Cross-Origin Resource Sharing (CORS), and defensive HTTP security headers (Content Security Policy / CSP, SameSite cookies).
This chapter details XSS execution vectors, CSRF mitigation (SameSite=Lax / anti-CSRF tokens), CORS Preflight OPTIONS handshakes, and security header configurations.
1. Cross-Site Scripting (XSS) & Content Security Policy (CSP)
Cross-Site Scripting (XSS) occurs when an application renders untrusted user input directly into the DOM without sanitization, allowing attackers to execute arbitrary JavaScript in the victimβs browser session:
- Reflected XSS: Malicious script injected via URL query parameters.
- Stored XSS: Malicious script saved directly in a database (e.g. comment field).
- DOM XSS: Client-side JavaScript unsafely parses input (
element.innerHTML = input).
XSS Mitigation Defense-in-Depth:
1. Contextual Output Encoding: Escape HTML entities (& -> &, < -> <) using auto-escaping engines (Jinja2).
2. HttpOnly Cookies: Set 'HttpOnly' flag on sensitive cookies so document.cookie cannot read them!
3. Content Security Policy (CSP): HTTP header restricting script execution sources:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.trusted.com2. Cross-Site Request Forgery (CSRF) & SameSite Cookies
CSRF tricks an authenticated userβs browser into sending an unintended HTTP request to a vulnerable target site where the user is currently logged in:
CSRF Attack Scenario:
1. User is logged into Target Bank (Session Cookie stored in browser).
2. User visits Attacker Website on another tab.
3. Attacker page executes: <img src="https://bank.com/transfer?amount=1000&to=attacker"/>
4. Browser AUTOMATICALLY includes bank.com session cookie! Transfer succeeds!CSRF Mitigations:
- Anti-CSRF Tokens: Include secret per-session tokens in forms (
Flask-WTF). SameSiteCookie Attribute:SameSite=Strict: Cookie is NEVER sent in cross-site requests.SameSite=Lax(Modern Default): Cookie is withheld on cross-site sub-requests (images, POSTs) but sent on top-level GET navigations.
3. Cross-Origin Resource Sharing (CORS) & Preflight OPTIONS
The Same-Origin Policy (SOP) enforces that a web browser restricts scripts running on Origin A (https://app.com) from reading data from Origin B (https://api.com).
CORS is an explicit browser protocol allowing servers to whitelist cross-origin access:
CORS Preflight Handshake Sequence:
[ Browser (Origin: https://app.com) ] ββ> OPTIONS /api/data ββ> [ FastAPI Backend ]
|
v Responds:
Access-Control-Allow-Origin: https://app.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type, Authorization
|
[ Browser Verifies Headers ] ββ> Executes ACTUAL GET /api/data Request!Critical CORS Anti-Pattern:
Setting Access-Control-Allow-Origin: * while simultaneously setting Access-Control-Allow-Credentials: true is forbidden by browsers and creates critical security holes!
4. Production Security Headers Checklist
| Security Header | Recommended Configuration | Purpose |
|---|---|---|
Content-Security-Policy | default-src 'self' | Prevents inline XSS and unauthorized script execution. |
Strict-Transport-Security | max-age=31536000; includeSubDomains | Forces browsers to communicate over HTTPS exclusively (HSTS). |
X-Content-Type-Options | nosniff | Prevents MIME-type sniffing attacks. |
X-Frame-Options | DENY / SAMEORIGIN | Prevents Clickjacking attacks in <iframe> embeds. |