Django CSRF Protection Guide: Examples and How to Enable (2024)

Sometimes it’s easier to build your website without thinking about security. And many times, perhaps due to tight timeframes, you might forget the need to factor in basic security measures.

It’s arguably easier to build websites or web apps without paying much attention to security and internet request protocols. But then, to what end?

  • Risking security hacks?

  • Risking attack from malicious requests?

  • Exposing your users to dangers from internet fraudsters?

For the good of your apps and your users, it makes sense to learn about security attacks in general — and to understand the need for and use of security measures for all your web applications in particular.

Many popular security attacks exist on the web. The cross-site request forgery (CSRF) is one of them.

In Django, there are several ways to prevent CSRF attacks.

In Django, there are several ways to prevent CSRF attacks. And for Django developers, Django’s measures against CSRF attacks are worth paying attention to.

In this post, we’ll talk about what CSRF is and how it works. Then, we’ll walk you through examples in Django and how to prevent them.

What Exactly Is CSRF?

CSRF (or XSRF) is also known as cross-site request forgery. As the name suggests, CSRF is a kind of attack on sites mostly done by other (malicious) sites, or sometimes by a (malicious) user on the site.

Typically, there are many cases where a site would require a user to fill in data from another website on behalf of that particular user. An example is how a lot of blogs use Disqus to power their commenting systems. To comment in that particular blog, the blog requires that you log in to Disqus first. This is a basic use of a CDN (content delivery network), and this example is a legitimate cross-site request.

CSRF attacks usually rely on the user's identity. So what happens when a user visits a malicious website? That site sends hidden forms of some JavaScript XMLHttpRequest. That request uses the credentials of a user (one who visited their malicious site) to do some actions on another website that trusts the user’s browser or identity.

A site usually identifies authenticated users by saving cookies with headers and content that represent that particular user in their browsers. Attackers use this to access the user’s credentials to perform their attacks.

An Example: Frank and the Bank

Some unknown attacker wants to access Frank’s bank account and steal his money. What happens if Frank’s bank is vulnerable to CSRF?

To transfer cash, Frank has to use a particular URL that's saved to his browser, such as http://example_a_bank.com/app/service/transfer?amount=20000&destination=example_b_bank&accountNumber=9567265100.

The transfer is successful. Then the browser saves a cookie session with Frank’s credentials, and Frank moves on.

The unknown attacker has a malicious website that Frank has probably innocently clicked. As a result, the attacker has placed an HTML code in the malicious website that looks like this:

<imgsrc="http://example_a_bank.com/app/service/transfer?amount=60000&destination=example_c_bank&accountNumber=9017265100"width="0px"height="0px">

Now when Frank visits the malicious website, the browser will think it's loading or processing an image link. It will issue a GET request to fetch the picture, but it will also send a request to Frank’s bank to transfer $60,000 to the attacker’s specified bank account. The actual bank still has a cookie session saved in Frank’s browser. Therefore, the bank's systems think this is a real request and process it.

This is a very serious vulnerability! How can banks and other businesses avoid this? Let’s dive into how to enable CSRF protection in Django.

How can banks and other businesses avoid vulnerabilities? Let's dive into how to enable CSRF protection in Django.

CSRF in Django

Powered by Python, Django is a free and open-source web framework that allows you to develop secure and maintainable websites in no time. Experienced developers built Django with the aim of reducing the unnecessary hassles of web development. This way, you can focus on building without having to reinvent the wheel. It's suitable for back-end and front-end development.

Middleware in Django is a set of functions that run during request and response processes. And in Django, there’s CSRF middleware that helps protect against CSRF attacks in Django apps.

When you start a Django project, you’ll see in your settings.py file that the middleware has been activated by default.

'django.middleware.csrf.CsrfViewMiddleware'

How to Use Django's CSRF Middleware

Step 1

You 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:

MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', #Csrf Middleware is added 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',]

However, if you override these settings, you can decide to put django.middleware.csrf.CsrfViewMiddleware before any middleware that assumes that CSRF attacks have been dealt with.

Step 2

Django has a template tag that makes it easy to use CSRF protection:

{% csrf_token %}

In a template that uses the POST form, use the csrf_token inside the <form> element.

<form action="" method="post"> {% csrf_token %}</form>

The CSRF Decorator Method

Do you want to use CSRF protection on a particular view? Then csrf_protect decorator is right for you. It’s got the same functionality as the CsrfViewMiddleware, but it works only on the views you assign it to.

from django.shortcuts import render from django.views.decorators.csrf import csrf_protect @csrf_protect def user(request):  user = {}  # ...  return render(request, "user_view.html", user)

NOTE: It's better to use CsrfViewMiddleware as an overall protection. If you forget to add the decorator to your views, it'll create security issues. You must use it on the views that assign CSRF tokens to the output and the ones that accept data from the POST form.

You can also use CsrfViewMiddleware as your blanket protection and still decide which view gets to use it. Like this:

from django.http import HttpResponsefrom django.views.decorators.csrf import csrf_exempt@csrf_exemptdef user(request): return HttpResponse('CSRF token is being exempted here!')

The csrf_exempt decorator marks the view and exempts it from the protection the middleware ensures on all views.

Other Decorator Methods

Here are some other methods you might find useful.

csrf_exempt(view): It marks a view as exempt from the CSRF protection.

requires_csrf_token(view): This ensures that the template tag csrf_token works. Its function is similar to crsf_protect, but it doesn't reject an incoming request.

ensure_csrf_cookie(views): This enforces a view to set a CSRF cookie, even if the csrf_token template tag isn't used.

How Does the CSRF Token Work?

The CSRF token is like an alphanumeric code or random secret value that's peculiar to that particular site. Hence, no other site has the same code.

In Django, the token is set by CsrfViewMiddleware in the settings.py file.

A hidden form field with a csrfmiddlewaretoken field is present in all outgoing requests. When you submit a form to the server that it didn’t send to you, the server won’t accept it—unless it has the CSRF token that matches the one the server recognizes.

The server has its own CSRF token. That's what it sends, along with a form to the client for protection of information.

All incoming requests must have a CSRF cookie, and the csrfmiddlewaretoken field must be present and correct. Otherwise, the user will get a 403 error.

Enabling Django CSRF Protection With Django REST and React

What about cases where you’re using Django REST and a separate front-end framework, such as React? You'll definitely want to ensure that you have CSRF protection enabled as well. Here’s how.

Using React Forms to Render a CSRF Token

Django templates allow you to easily include:

{% csrf_token %}

inside forms. However, in React, you’ll have to go the longer route to render it yourself.

Step 1

You have to fetch the csrf token from Django's csrf_token cookie. But this will be set only if the CSRF middleware is enabled in Django.

In Django’s official documents, here’s the way to get the token in JavaScript:

function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue;}

You can now retrieve the token as shown below:

const csrftoken = getCookie('csrftoken');

Step 2

You can then create a global csrftoken.js file that has the following:

import React from 'react';const csrftoken = getCookie('csrftoken');const CSRFTOKEN = () => { return ( <input name="csrfmiddlewaretoken" value={csrftoken} type="hidden" /> );};export default CSRFTOKEN;

It’s now easier to import and include it inside as many forms as possible:

import CSRFTOKEN from './csrftoken';class SampleForm extends Component { render() { return ( <form action="/" method="POST"> <CSRFTOKEN /> ... </form> ); }}export default SampleForm;

Sending a FETCH Request With Django CSRF Token in React

Also, you can also now easily send a React FETCH request while assigning the csrf_token X-CSRFToken header:

 fetch(url, { credentials: 'include', method: 'POST', mode: 'same-origin', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'X-CSRFToken': csrftoken }, body: {} }) }

There! You’ve been able to include Django’s csrf_token in React.

Conclusion

You've now learned what CSRF protection is and how to enable it in Django. This means you're one step ahead of security attacks and malicious attempts against your users.

To learn even more, check out this post.You can also review this example on how other tools integrate CSRF tokens to perform automated authentication testsfrom StackHawk.

This post was written by Juan Pablo Macias Gonzalez. Juan is a computer systems engineer with experience in backend, frontend, databases and systems administration.

StackHawk

|

June 15, 2021

Django CSRF Protection Guide: Examples and How to Enable (2024)

FAQs

Django CSRF Protection Guide: Examples and How to Enable? ›

To protect MVC applications, Spring adds a CSRF token to each generated view. This token must be submitted to the server on every HTTP request that modifies state (PATCH, POST, PUT and DELETE — not GET). This protects our application against CSRF attacks since an attacker can't get this token from their own page.

How to enable CSRF in Django? ›

To take advantage of CSRF protection in your views, follow these steps:
  1. The CSRF middleware is activated by default in the MIDDLEWARE setting. ...
  2. In any template that uses a POST form, use the csrf_token tag inside the <form> element if the form is for an internal URL, e.g.:

How do I enable CSRF protection? ›

To protect MVC applications, Spring adds a CSRF token to each generated view. This token must be submitted to the server on every HTTP request that modifies state (PATCH, POST, PUT and DELETE — not GET). This protects our application against CSRF attacks since an attacker can't get this token from their own page.

How does Django protect against CSRF attacks? ›

The CSRF protection is based on the following things: A CSRF cookie that is a random secret value, which other sites will not have access to. CsrfViewMiddleware sends this cookie with the response whenever django. middleware.

Where is CSRF token stored in Django? ›

Token Generation

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.

How does CSRF protection work? ›

CSRF tokens can prevent CSRF attacks, because they prevent attackers from forming fully valid HTTP requests, which they can feed to a victim. The attacker cannot determine or predict the value of the user's CSRF token, so any request they generate should not be accepted by the application.

How do I fix CSRF error? ›

Clear Cookies from the Browser

Old or corrupted cookies can cause a CSRF token mismatch error. To clear cookies, go to your browser settings and find the option to clear browsing data or cookies. Once the cookies are cleared, try to perform the action that was causing the error again.

When should I enable CSRF? ›

Enabling cross-site request forgery (CSRF) protection is recommended when using REST APIs with cookies for authentication.

Is CSRF enabled by default? ›

In Spring Security, CSRF (Cross-Site Request Forgery) protection is enabled by default. However, you can explicitly enable or disable CSRF protection based on your application's requirements.

How do I enable cookies in CSRF? ›

Chrome
  1. Open Chrome Settings.
  2. Scroll to the bottom and click on Advanced.
  3. In the Privacy and security section, click the Content Settings button.
  4. Click on Cookies.
  5. Next to Allow, click Add. ...
  6. Under All cookies and site data, search for ubidots, and delete all ubidots-related entries.

Do you need CSRF for Django rest framework? ›

If you're using SessionAuthentication you'll need to include valid CSRF tokens for any POST , PUT , PATCH or DELETE operations. In order to make AJAX requests, you need to include CSRF token in the HTTP header, as described in the Django documentation.

How to provide security in Django? ›

Always keep Django and your application's dependencies up-to-date to keep up with security vulnerabilities. Ensure that the application is never in DEBUG mode in a production environment. Never run DEBUG = True in production. Use packages like django_ratelimit or django-axes to prevent brute-force attacks.

How to make Django secure? ›

Django Security Best Practices: Fortifying Your Web Application
  1. Keep Django Up-to-Date. ...
  2. Enable Debug Mode Carefully. ...
  3. Secure Your Django Admin Panel. ...
  4. Implement Strong Authentication. ...
  5. Protect Against Cross-Site Request Forgery (CSRF) ...
  6. Prevent SQL Injection. ...
  7. Validate and Sanitise User Input. ...
  8. Use Django's Security Middleware.
Sep 13, 2023

Where do I put CSRF tokens? ›

Place the field containing the CSRF token as early as possible within the HTML file. Place the field that contains the token before any non-hidden fields and before any places where user-controllable data is embedded.

How to add CSRF token in Postman Django? ›

3. Postman
  1. 3.1. Testing Without CSRF Token. Let's open Postman and add a new request: ...
  2. 3.2. X-XSRF-TOKEN Header Property. In the Headers tab, let's add a new parameter called X-XSRF-TOKEN and the value set to xsrf-token. ...
  3. 3.3. Environment Variable xsrf-token. ...
  4. 3.4. Script. ...
  5. 2.5. Testing.

How authentication works in Django? ›

The Django authentication system handles both authentication and authorization. Briefly, authentication verifies a user is who they claim to be, and authorization determines what an authenticated user is allowed to do. Here the term authentication is used to refer to both tasks.

How do I enable logging in Django? ›

In order to configure logging, you use LOGGING to define a dictionary of logging settings. These settings describe the loggers, handlers, filters and formatters that you want in your logging setup, and the log levels and other properties that you want those components to have.

How do I add CSRF token to header? ›

Put together the CSRF header, as follows:
  1. Capture the name and the value of the Csrf-Token_{FedMemberID} cookie returned with the login response. For example, the name might be Csrf-Token_acmepaymentscorp. ...
  2. For the header name, prepend X-. ...
  3. For the header value, use the cookie value.

How to make user authentication in Django? ›

The main index page should have a “Users” link in the “Auth” section. Unlike other admin pages, “Add user” requires choosing a username and password before you can edit other fields. You must give “add user” and “change user” permissions to any user account that will be creating users via Django Admin.

Top Articles
Latest Posts
Article information

Author: Kerri Lueilwitz

Last Updated:

Views: 6532

Rating: 4.7 / 5 (67 voted)

Reviews: 90% of readers found this page helpful

Author information

Name: Kerri Lueilwitz

Birthday: 1992-10-31

Address: Suite 878 3699 Chantelle Roads, Colebury, NC 68599

Phone: +6111989609516

Job: Chief Farming Manager

Hobby: Mycology, Stone skipping, Dowsing, Whittling, Taxidermy, Sand art, Roller skating

Introduction: My name is Kerri Lueilwitz, I am a courageous, gentle, quaint, thankful, outstanding, brave, vast person who loves writing and wants to share my knowledge and understanding with you.