Django csrf validates the implementation of the problem

  • 2020-12-13 19:00:10
  • OfStack

A basic understanding of csrf

CSRF (ES5en-ES6en request forgery) cross-site request forgery, usually abbreviated to CSRF or XSRF, is a malicious use of a website. Exploit trusted websites by disguising requests from trusted users.

Simply put, the attacker is stealing your identity and sending malicious requests in your name. For example, the user accesses the website A through the account password, and the A website saves some cookie information in the browser to realize the status and behavior tracking of the user. When the user opens the B website, the B website returns 1 malicious code and requests access to A. The browser then takes cookie to the A site with the user's permission and executes the code. From the server's point of view, these are normal user actions.

CSRF protection mechanism provided by Django

The first time django responds to a request from a client, it randomly generates an token on the server side and places the token in cookie. And then every POST request brings this token,

This way you can avoid being attacked by CSRF.

1. In the cookie of the returned HTTP response, django will add one csrftoken field for you, with the value of one automatically generated token
2. All POST forms must contain 1 csrfmiddlewaretoken field (just add 1 tag to the template and django will automatically generate for you, see below)
3. Before processing an POST request, django verifies that the value of the csrftoken field in the cookie of the request is the same as the value of the csrfmiddlewaretoken field in the submitted form. If this is 1, it indicates that this is a legitimate request. Otherwise, this request may be from someone else's csrf attack. Return 403 Forbidden.
4. Add 1 X-ES61en header to all ajax POST requests, the value of which is csrftoken in cookie

How to use CSRF protection in Django

First, the bottom line is: GET requests do not have side effects. That is, any code that handles GET requests must have "read-only" access to the resource. To enable the django. middleware. csrf. CsrfViewMiddleware the middleware Third, add one {% csrf_token %} tag to all POST form elements RequestContext is used when rendering modules. RequestContext processes csrf_token, the tag, to automatically add an input named csrfmiddlewaretoken to the form

Precautions against csrf in Django

Django comes with a built-in protection against csrf attacks, but for beginners you may not know how to use it and may cause you some unexpected problems.

For example: a normal form submission operation always reports an error.

GET requests in Django do not require csrf authentication, post requests require the correct authentication to get the correct return results.

Let's first deal with the csrf validation issue for form submission: 1 generally add {% csrf_token %} to POST form


<form method="POST" action="#">
{% csrf_token %}
  <input name='password' value=' The user password '>
</form>

With this added, you can submit the post form again without any problems.

Or another idea: ban csrf

But you have to think about the risks.

Global disabled: Middleware for csrf is found in the settings file, annotated directly.

Targeted disable: Add a decorator @csrf_ES130en to the corresponding view function for form submission

-- -- -- -- -- -- -- -- -- -- --

{% csrf_token %} is actually a template syntax that writes the token value of the project to the form on the front page, which was automatically generated when the django project was set up and can be seen in setting.

-- -- -- -- -- -- -- -- -- -- -- �

Now let's look at how the Ajax call is handled in 1

You can add 1 section of js code before using ajax or post for jquery


jQuery(document).ajaxSend(function(event, xhr, settings) {
  function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
      var cookies = document.cookie.split(';');
      for (var i = 0; i < cookies.length; i++) {
        var cookie = jQuery.trim(cookies[i]);
        // 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;
  }
  function sameOrigin(url) {
    // url could be relative or scheme relative or absolute
    var host = document.location.host; // host + port
    var protocol = document.location.protocol;
    var sr_origin = '//' + host;
    var origin = protocol + sr_origin;
    // Allow absolute or scheme relative URLs to same origin
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
      (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
      // or any other URL that isn't scheme relative or absolute i.e relative.
      !(/^(\/\/|http:|https:).*/.test(url));
  }
  function safeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
  }

  if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
  }
});

Or write directly to the template file


$.ajaxSetup({
  data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});

Related articles: