Django provides a feature known as a CSRF token to get away from CSRF attacks that can be very dangerous. when the session of the user starts on a website, a token is generated which is then cross-verified with the token present with the request whenever a request is being processed.
What is a CSRF?
CSRF means cross-site request forgery. In this type of attack, the attacker sends a link in the form of sms, email, or chat. In this way, the attacker tricks the user who is already authenticated on the website to perform various actions such as transfer of funds, change of email, and so on. Depending upon the nature of the attack the attacker may take full access to the account.
Syntax of CSRF Token in Django
{% csrf_token %}
What is CSRF Token in Django?
Django provides a feature to prevent such types of malicious attacks. When a user is authenticated and surfing on the website, Django generates a unique CSRF token for each session. This token is included in forms or requests sent by the user and is checked by the server to verify that the request is coming from the authenticated user and not from a malicious source.
While CSRF protection primarily focuses on protecting against actions that make changes in data, it's still a good practice to include CSRF tokens in forms generated by Django, even for GET requests. This can help prevent attackers from creating malicious forms that trick users into making unwanted changes.
CSRF tokens are an important security feature in Django. To explore Django's security mechanisms and other advanced features, the Complete Django Web Development Course - Basics to Advance is an excellent resource.
Working of CSRF Protection
To understand this let us take an example. Suppose you are logged into the website. The attacker sends a link with the help of an email, chat, or with the use of sms. The link contains the request which the attacker wants to be performed. As the user is already authenticated on the website the request is completed when he clicks on the link. This type of request is very dangerous as it may take complete access to the data and other harmful actions may be performed such as transfer of funds, change of email and so on.
Token Generation
When a user logs in or starts a session, Django generates a random and unique CSRF token for that session. This token is usually a long string of characters. This token is associated with the user's session and stored on the server.
CsrfViewMiddleware
sends this cookie with the response whenever django.middleware.csrf.get_token()
is called. It can also send it in other cases. For security reasons, the value of the secret is changed each time a user logs in.
When Django renders an HTML form using a template, it includes the CSRF token using the {% csrf_token %}
template tag. The CSRF token should be added as a hidden input field in the form.
Example
HTML
<form method="post">
{% csrf_token %}
<!-- Other form fields here -->
<button type="submit">Submit</button>
</form>
Token Validation on Submission
When the user submits the form, the CSRF token is sent along with the request, either as a POST parameter or a request header (e.g., X-CSRFToken
). The token is extracted from the request by the server. It is then verified that if this token (received in request) matches with the token which is linked with the user's session. If the token matches, the request is considered as valid and we can proceed with it. If they don't match, then the server interprets it as it may be a CSRF attack and rejects the request.
How to Use Django's CSRF Middleware?
We need to add django.middleware.csrf.CsrfViewMiddleware in the settings.py file to enable it. By default, Django already has this enabled, as in the following example:
CSRF Middleware Let us create HTML page in which usersubmits a form. We have included the {%csrf_token%} as a hidden field in our HTML code.
HTML file
HTML
<form method="post">
{% csrf_token %}
<form action="/your-name/" method="post">
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" value="{{ current_name }}">
<button type="submit">Submit</button>
</form>
The CSRF Decorator Method
When we want that our CSRF should work only for particular view then we can use Decorator method in which have to place '@csrf_protect' at the top of that function as shown below in the views.py file
Views.py
Python
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def simulate_csrf_error(request):
if request.method == 'POST':
return HttpResponse("Form submitted successfully!")
return HttpResponse("GET request, please submit the form.")
How Does the CSRF Token Work?
Now suppose a user who is already authenticated on the website tries to submit the form , the request is easily processed and the data is submitted. Now suppose an attacker sends an link to the authenticated user to submit a information as in this case the csrf token will not match with the token generated for the user at the starting of the session, so it will throw a error 403 as shown below.
csrf token mismatch error in django In this way csrf_token in django helps in preventing attacks from malicious attackers.
Using CSRF protection with AJAX
When making AJAX or API requests from JavaScript , we need to manually include the CSRF token in the request headers.
Assume that we have a page where we want to send data to a Django API endpoint using AJAX. We need to include the CSRF token as a header in our AJAX request. We can acquire the token as shown in the below example:
The JavaScript code in the HTML page extracts the CSRF token from the cookie using the getCookie
function and sends a POST request to the Django API endpoint.
HTML
<!DOCTYPE html>
<html>
<head>
<title>API Request Example</title>
<script>
// Function to get the CSRF token from the cookie
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
// Function to send a POST request with CSRF token
function sendPostRequest() {
const csrfToken = getCookie('csrftoken');
const url = '/api/some_endpoint/';
const data = { key: 'value' };
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken // Include the CSRF token in the header
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
console.log('Response from server:', data);
})
.catch(error => {
console.error('Error:', error);
});
}
</script>
</head>
<body>
<button onclick="sendPostRequest()">Send POST Request</button>
</body>
</html>
Another way to use CSRF protection in Jinja2 Templates
Django’s Jinja2
template backend adds {{ csrf_input }}
to the context of all templates which acts same as {% csrf_token %}
in the Django template language. For example:
HTML
<form method="post">{{ csrf_input }}
Similar Reads
Navigation in Django
Navigation refers to how users move through different sections of a web application. In Django, navigation is handled by combining URLs, views, and templates. By defining URL patterns, associating them with views, and linking them in templates, we can create a seamless experience for users as they m
4 min read
Student Report Card in Django
In this Django project, we will develop a student report card system that displays individual subject marks, calculates the total marks obtained, and ranks students based on their performance. This project aims to provide a user-friendly platform for students to easily access and analyze academic da
7 min read
Views In Django | Python
Django Views are one of the vital participants of the MVT Structure of Django. As per Django Documentation, A view function is a Python function that takes a Web request and returns a Web response. This response can be the HTML contents of a Web page, a redirect, a 404 error, an XML document, an ima
6 min read
How to Create an App in Django ?
Prerequisite - How to Create a Basic Project using MVT in Django? Django is famous for its unique and fully managed app structure. For every functionality, an app can be created like a completely independent module. This article will take you through how to create a basic app and add functionalities
4 min read
CharField - Django Models
CharField is a string field, for small- to large-sized strings. It is like a string field in C/C++. CharField is generally used for storing small strings like first name, last name, etc. To store larger text TextField is used. The default form widget for this field is TextInput. CharField has one e
4 min read
CSRF Protection in Flask
Cross-Site Request Forgery (CSRF) is a security vulnerability where an attacker tricks a user into unknowingly submitting a request to a web application in which they are authenticated. This can lead to unauthorized actions being performed on behalf of the user, such as changing account settings or
3 min read
CharField - Django Forms
CharField in Django Forms is a string field, for small- to large-sized strings. It is used for taking text inputs from the user. The default widget for this input is TextInput. It uses MaxLengthValidator and MinLengthValidator if max_length and min_length are provided. Otherwise, all inputs are vali
5 min read
Custom Template Filters in Django
Django is a Python-based web framework that allows you to quickly create efficient web applications. It is also called batteries included framework because Django provides built-in features for everything including Django Admin Interface, default database â SQLlite3, etc. What is filters in Django t
2 min read
Python | Django Admin Interface
Prerequisites: Django Introduction and Installation Creating a ProjectThe Django Admin Interface is one of the most powerful features of the Django framework. It provides a ready-to-use interface for managing project data through models, allowing developers and site administrators to perform Create,
3 min read
How to create superuser in Django?
Django comes with a built-in admin panel that allows developers to manage the database, users and other models efficiently. This eliminates the need for creating a separate admin interface from scratch. To access and manage the Django Admin panel, we need to create a superuser i.e. a user with full
2 min read