🛡️ Practically Understand CSRF Token in Django

CSRF is one of the most common web fundamentals that every web developer must understand.
CSRF stands for Cross Site Request Forgery. As the name suggests, it involves a situation where a malicious site tricks a browser into sending a request to another site where the user is already authenticated.

If not understood and implemented properly, CSRF can open dangerous loopholes — like allowing someone to create, modify, or delete data without your user's consent.

Why Is There A Need For Anti-CSRF Token ? | by Zullu Natal | Medium


🔧 Let's Build a CSRF Demo in Django

We’ll create a small Django project to understand CSRF in action — both with and without protection.

Step 1: Project Setup

django-admin startproject csrf_demo
cd csrf_demo
python manage.py startapp home

Step 2: Create a Model

from django.db import models

class Student(models.Model):
    name = models.CharField(max_length=100)
    roll = models.CharField(max_length=20)
    address = models.TextField()
python manage.py makemigrations
python manage.py migrate

Step 3: Create Superuser

python manage.py createsuperuser

Step 4: Create a CSRF-Exempt View

from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
from django.shortcuts import render
from .models import Student

@csrf_exempt
def create_student(request):
    if request.method == "POST":
        name = request.POST.get('name')
        roll = request.POST.get('roll')
        address = request.POST.get('address')
        Student.objects.create(name=name, roll=roll, address=address)
        return HttpResponse("New Student Created")
    return render(request, 'create.html')

Step 5: Setup Template

Make sure templates are configured in settings.py, and then create templates/create.html:

<h2>Create Student</h2>
<form method="post" action="">
    <input type="text" name="name" placeholder="Name"><br>
    <input type="text" name="roll" placeholder="Roll"><br>
    <input type="text" name="address" placeholder="Address"><br>
    <button type="submit">Create</button>
</form>

Step 6: Configure URLs

from django.urls import path
from .views import create_student

urlpatterns = [
    path('create/', create_student, name="create")
]

Step 7: Run the Server

python manage.py runserver

Visit: http://localhost:8000/create/

Folder structure

Browser interface

Open the file in a browser and click Submit. The form will be submitted without permission due to missing CSRF protection.


🕵️ Simulate a CSRF Attack

Create an HTML file outside your Django project and paste this:

<h3>This is the attacker site</h3>
<form action="http://localhost:8000/create/" method="post">
    <input type="text" name="name" value="Hacked"><br>
    <input type="text" name="roll" value="666"><br>
    <input type="text" name="address" value="Unknown"><br>
    <button type="submit">Submit</button>
</form>

Open the file in a browser and click Submit. The form will be submitted without permission due to missing CSRF protection.


🔐 Now Let's Enable CSRF Protection

Remove @csrf_exempt from the view. Django now automatically protects the view by rejecting POST requests without a CSRF token.

Update your form template to include the CSRF token:

<form method="post" action="">
    {% csrf_token %}
    <input type="text" name="name" placeholder="Name"><br>
    <input type="text" name="roll" placeholder="Roll"><br>
    <input type="text" name="address" placeholder="Address"><br>
    <button type="submit">Create</button>
</form>

Now the form is protected, and attackers can't forge a request without the secret CSRF token.

Same request will show this page: