Cross-Site Request Forgery (CSRF) is a critical web security vulnerability where a malicious third-party site tricks an authenticated user's browser into executing unauthorized mutations (e.g. changing passwords, transferring funds, or updating records) on a trusted application. Django includes an industry-leading, built-in CSRF defense framework.
1. How CSRF Attacks Work
Output
11. User logs into https://bank.enterprise.com (Session cookie is set in browser)
22. In another tab, user visits https://malicious-site.com
33. Malicious site automatically submits hidden form:
Single Page Applications (React, Vue) sending JSON requests (application/json) cannot use HTML form inputs. Instead, Django places the CSRF token in a readable cookie (csrftoken), which the frontend sends in the X-CSRFToken HTTP header:
Python
1# config/settings.py
2# Set cookie to be accessible by client JavaScript for AJAX/React:
3CSRF_COOKIE_HTTPONLY =False
4CSRF_COOKIE_SAMESITE ="Lax"
In React / Axios:
TypeScript
1import axios from"axios";
2
3// Helper to extract cookie value
4functiongetCookie(name:string):string|null{
5const match = document.cookie.match(newRegExp("(^| )"+ name +"=([^;]+)"));
6return match ?decodeURIComponent(match[2]):null;
7}
8
9// Global Axios configuration: automatically attaches Django CSRF token
10axios.interceptors.request.use((config)=>{
11const csrfToken =getCookie("csrftoken");
12if(csrfToken && config.headers){
13 config.headers["X-CSRFToken"]= csrfToken;
14}
15return config;
16});
4. Exempting Webhooks with @csrf_exempt
External incoming webhooks (e.g. Stripe, GitHub, Twilio) originate from third-party servers that do not possess browser sessions or CSRF tokens. Exempt these specific endpoints defensively: