Sunday, December 15, 2019

Python 3.7.5 : Simple intro in CSRF.

CSRF or Cross-Site Request Forgery is a technique used by cyber-criminals to force users into executing unwanted actions on a web application.
To protect against web form CSRF attacks, it's isn't sufficient for web applications to trust authenticated users, must be equipped with a unique identifier called a CSRF token similar to a session identifier.
Django 3.0 can be used with CSRF, see the documentation page.
The CSRF process is a simple one in Django framework.
However, it's highly recommended to use the CsrfViewMiddleware instead.
To activate the django.middleware.csrf.CsrfViewMiddleware in the settings.py file.
Basically, you can use the decorator method in the view.py file.
For example, see documentation:
@csrf_protect
However csrf_protect will check only POST requests.
This annotation CSRF tells Django I'm not handling CSRF properly and don't fail this.
If I don't use this annotation then the CSRF is on if the post request is on by default and I will receive a 403 error.
As the developer using templates you don't have to know anything about that and you can use this in your template HTML5 file.
{% csrf_token %}
I can use the token with my code if I want to send it to the website.
from django.middleware.csrf import get_token
Then this can be used in view.py with a hidden form field with the name csrfmiddlewaretoken present in all outgoing POST forms.
You can used in any forms tag area like: input ...

def my_csrf_form(request):
    response = """ ... type = "hidden" name = "csrfmiddlewaretoken" value = "__token__" ... """
This can be used with:
token = get_token(request)
response = response.replace('__token__', html.escape(token))
response += dumpdata('POST', request.POST)
return HttpResponse(response)
This will get a token for the current request and fill into value = "__token__".
Using my old example from GitHub.
First, I start the project:

[mythcat@desk projects]$ source django/env/bin/activate
(env) [mythcat@desk projects]$ ls
cache  django  kaggle  logs  OSMnx  pygal_ex  SantaClaus.py
(env) [mythcat@desk projects]$ cd django/
(env) [mythcat@desk django]$ ls
env  mysite  venv
(env) [mythcat@desk django]$ cd mysite/
I change the chart.html file with this before javascript script:
... {% csrf_token %} ... 
You can use it in javascript - jQuery like this, if you want:
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
The CSRF protection on Django on my form can bu used in view.py:
...
# use csrf_protect
from django.views.decorators.csrf import csrf_protect
from django.utils.decorators import method_decorator
...
# define view for chart 
class Test001ChartView(TemplateView):
    csrf_protected_method = method_decorator(csrf_protect)
I test it and works well.
The documentation tells us:
The CSRF protection cannot protect against man-in-the-middle attacks, so use HTTPS with HTTP Strict Transport Security. It also assumes validation of the HOST header and that there aren’t any cross-site scripting vulnerabilities on your site (because XSS vulnerabilities already let an attacker do anything a CSRF vulnerability allows and much worse).