Understanding CSRF Tokens: How to Protect Your Website from Cross-Site Request Forgery Attacks

Rohit RanjanRohit Ranjan
4 min read

Introduction

In today's world of online applications, security is one of the top priorities. One common yet dangerous attack is Cross-Site Request Forgery (CSRF). But don't worry—CSRF tokens are here to protect your website and its users. In this article, we'll break down what a CSRF token is, why it's needed, how it works, and what happens if you don't use it. We'll also walk through how Django handles CSRF protection.


What is a CSRF Token?

A CSRF token is a unique security token generated by the server that is used to verify that the requests sent to the server are genuine and come from authenticated users. It helps prevent malicious websites from making unwanted requests on behalf of the user without their consent.


Why is CSRF Token Needed?

In simple terms, CSRF tokens are needed to ensure that the person performing an action on a website is the actual user and not a malicious attacker. Websites trust users based on their authentication status (i.e., logged in users), and without CSRF protection, these trust relationships can be exploited.

When you’re logged in to a website, your browser stores session cookies, which identify you as a valid user. However, attackers can take advantage of this by tricking you into making requests to perform actions like changing your password, sending money, or updating your account—all without your knowledge.


How Websites Can Be Exploited Without CSRF Protection

Imagine you are logged into your bank's website, and you visit a malicious website. The attacker could create a hidden form that makes a request to transfer funds from your account to theirs without you ever realizing it. Here's how it works:

  1. You’re logged into your bank website (session active).

  2. The attacker’s website contains malicious code, such as:

     <img src="https://yourbank.com/transfer?amount=1000&to=attacker" />
    
  3. This image tag is a hidden GET request to the bank's server, transferring money to the attacker's account. Since you’re already logged in, your browser sends the authentication cookies, and the server processes the request as if it came from you.

  4. CSRF attack successfully executed without your knowledge.

This is where the CSRF token comes into play. It prevents such attacks by ensuring that only legitimate requests from your site (with the correct CSRF token) are processed.


How CSRF Protection Works Internally in Django

Django’s CSRF protection works by generating a unique token for each user session. This token is then required to be included with each POST request made to the server. If the request doesn’t include a valid token, Django will reject it. Here's how Django's CSRF protection works step-by-step:

  1. Token Generation: Each time a user loads a page with a form, Django generates a unique CSRF token for that session.

  2. Token Insertion: The token is inserted into the form as a hidden field, using the {% csrf_token %} template tag.

  3. Token Validation: When the form is submitted, the server checks that the submitted token matches the token stored in the user's session.

  4. If Token is Invalid: If the tokens do not match, the request is rejected, and an error is raised.


Django Code Example: Handling CSRF Protection

Here’s an example of how Django uses CSRF tokens to protect forms:

1. Setting Up CSRF Token in a Form

<form method="post">
    {% csrf_token %}
    <label for="name">Your Name:</label>
    <input type="text" id="name" name="name">
    <button type="submit">Submit</button>
</form>
  • The {% csrf_token %} tag generates the CSRF token and places it in the form.

2. Handling POST Requests in Django View

from django.shortcuts import render
from django.http import HttpResponse

def contact_view(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        # process form data here
        return HttpResponse(f"Hello, {name}! Your form was successfully submitted.")
    return render(request, 'contact.html')
  • If the request is POST, Django will check if the CSRF token in the form is valid.

  • If valid, it processes the form; if invalid, it rejects the request.

3. CSRF Token in AJAX Requests

For AJAX requests, the CSRF token needs to be sent in the headers of the request.

function getCSRFToken() {
    return document.querySelector('[name=csrfmiddlewaretoken]').value;
}

fetch('/submit/', {
    method: 'POST',
    headers: {
        'X-CSRFToken': getCSRFToken(),
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ name: "Rohit" })
});
  • The JavaScript function sends the CSRF token in the X-CSRFToken header, ensuring that the request is protected against CSRF.

What Happens If CSRF Token is Not Used?

Without CSRF protection, attackers can forge requests that appear to come from trusted users. Here’s a summary of the risks:

  • Unauthorized actions (e.g., changing account details, submitting forms).

  • Security vulnerabilities in the website, making it susceptible to attacks.

  • Loss of user trust if sensitive data is exposed.

Django’s built-in CSRF protection effectively mitigates these risks by ensuring only legitimate requests are processed.


Conclusion

CSRF tokens are crucial for protecting web applications from malicious attacks. By validating requests with a unique token, Django ensures that only trusted users can perform actions on the website. Here’s a quick recap:

  • CSRF tokens prevent unauthorized actions by ensuring requests come from legitimate sources.

  • Without CSRF protection, attackers can perform unwanted actions on behalf of authenticated users.

  • Django automatically provides CSRF protection for forms and AJAX requests, requiring a valid token for POST requests.

0
Subscribe to my newsletter

Read articles from Rohit Ranjan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rohit Ranjan
Rohit Ranjan

I am a software Developer, interested in topics like Python, Django, Backend Development, Data Analysis, Cloud and AI. I learn and write about these topics when i find something interesting