CSRF token missing or incorrect

Loading

What is CSRF?

CSRF (Cross-Site Request Forgery) is a security mechanism that prevents unauthorized requests from being made on behalf of an authenticated user.

When a request is made to a protected endpoint without a valid CSRF token, the server rejects it, leading to the error:

403 Forbidden: CSRF token missing or incorrect.

Common Causes & Fixes

1️⃣ CSRF Token Missing in AJAX or API Request

Error Message:

403 Forbidden: CSRF token missing or incorrect.

If you’re making an API request via JavaScript (fetch, Axios, jQuery, etc.) and don’t send the CSRF token, Django/Flask rejects it.

Fix: Pass CSRF Token in Headers

  • Django (Frontend Example)
    Add the CSRF token from a cookie in JavaScript: function getCSRFToken() { return document.cookie.split('; ') .find(row => row.startsWith('csrftoken=')) ?.split('=')[1]; } fetch('/api/data/', { method: 'POST', headers: { 'X-CSRFToken': getCSRFToken(), 'Content-Type': 'application/json' }, body: JSON.stringify({ key: "value" }) });
  • Flask (Frontend Example) fetch('/api/submit', { method: 'POST', headers: { 'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').content, 'Content-Type': 'application/json' }, body: JSON.stringify({ data: "test" }) });

2️⃣ CSRF Token Not Included in HTML Form

Error Message:

403 Forbidden: CSRF token missing.

If you’re submitting a Django form, the CSRF token must be included.

Fix: Add {% csrf_token %} Inside the Form

<form method="post">
{% csrf_token %}
<input type="text" name="name">
<button type="submit">Submit</button>
</form>

3️⃣ CSRF Middleware Not Enabled in Django

If CSRF protection is disabled, requests will fail unexpectedly.

Fix: Ensure Middleware is Enabled in settings.py

MIDDLEWARE = [
'django.middleware.csrf.CsrfViewMiddleware', # Ensure this is present
]

4️⃣ CSRF Exempt in Django for API Requests

If using APIs (React, Vue, Angular, etc.), Django’s CSRF protection might block non-browser requests.

Fix: Use @csrf_exempt for APIs (if safe)

from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse

@csrf_exempt
def api_view(request):
return JsonResponse({"message": "Success"})

OR
Use Django REST Framework’s CSRF exemption:

from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny

@api_view(['POST'])
@permission_classes([AllowAny])
def api_view(request):
return JsonResponse({"message": "Success"})

5️⃣ CSRF Cookie Not Set or Expired

CSRF tokens are often stored in cookies, and missing/expired cookies can trigger this error.

✅ Fix: Ensure CSRF Cookie is Sent in Response

  • Django (Ensure Cookie is Set)
    In settings.py: CSRF_COOKIE_NAME = "csrftoken" CSRF_COOKIE_SECURE = False # Set True in production (HTTPS only) In views.py: pythonCopyEditfrom django.middleware.csrf import get_token from django.http import JsonResponse def set_csrf_token(request): return JsonResponse({"csrfToken": get_token(request)})
  • Frontend Request Example (JavaScript) fetch('/set-csrf-token/', { credentials: 'include' }) // Fetch token first .then(response => response.json()) .then(data => console.log("CSRF Token:", data.csrfToken));

6️⃣ CSRF Protection in Flask (Flask-WTF or Flask-SeaSurf)

Flask does not enable CSRF protection by default, but if you’re using Flask-WTF or Flask-SeaSurf, missing tokens can cause issues.

✅ Fix: Add CSRF Token in Flask Forms

from flask_wtf import FlaskForm
from wtforms import StringField
from flask_wtf.csrf import CSRFProtect

csrf = CSRFProtect(app)

class MyForm(FlaskForm):
name = StringField('Name')
  • Include Token in HTML Forms <form method="POST"> {{ form.hidden_tag() }} <!-- Includes CSRF token --> <input type="text" name="name"> <button type="submit">Submit</button> </form>
  • Flask API Request (Allow JSON Requests) from flask import Flask, request, jsonify from flask_cors import CORS from flask_wtf.csrf import CSRFProtect app = Flask(__name__) CORS(app) csrf = CSRFProtect(app) @app.route('/api/data', methods=['POST']) def api_data(): return jsonify({"message": "Success"})

7️⃣ CSRF Token Not Sent in Axios (React, Vue, etc.)

If using Axios for API calls, it may not send the CSRF token by default.

✅ Fix: Add CSRF Token in Headers

import axios from "axios";

axios.defaults.withCredentials = true;

axios.post('/api/data', { key: "value" }, {
headers: { 'X-CSRFToken': getCSRFToken() }
});

Debugging Tips

  1. Check if CSRF token is missing:
    • Open DevTools → Network Tab → Click on the failed request → Check Headers.
  2. Ensure CSRF token is included in requests: console.log(document.cookie); // Check if "csrftoken" exists
  3. Check Django logs for errors: tail -f logs/error.log

Leave a Reply

Your email address will not be published. Required fields are marked *