We always use csrf_token in Django forms, and it generated dynamically. If capture my session with fiddler and try to submit my form without that token I get a 403 error. But what I don't understand is I can use fiddler to submit as much data as I want with that same token, so I don't understand the security this token does. If someone hacks your forms they can just use the same token.
Am I missing some addition steps to assure that token is always unique?
csrf_token. Django has a {% csrf_token %} tag that is implemented to avoid malicious attacks. It generates a token on the server-side when rendering the page and makes sure to cross-check this token for any requests coming back in. If the incoming requests do not contain the token, they are not executed.
A CSRF token is a secure random token (e.g., synchronizer token or challenge token) that is used to prevent CSRF attacks. The token needs to be unique per user session and should be of large random value to make it difficult to guess. A CSRF secure application assigns a unique CSRF token for every user session.
The view itself is @csrf_exempt because API keys need to work. You don't need to check on each request, as CSRF tokens should only really be used on POST and PUT requests. Second, you can't verify a CSRF token unless you are generating it on each request, and your verification is optional.
CSRF protection works by checking for a secret in each POST request. This ensures that a malicious user cannot “replay” a form POST to your website and have another logged in user unwittingly submit that form. The malicious user would have to know the secret, which is user specific (using a cookie).
Different sites or frameworks have different CSRF protection mechanisms. Django protects against CSRF attacks by generating a CSRF token in the server, send it to the client side, and mandating the client to send the token back in the request header.
When generating a CSRF token in Django you'll notice that it automatically creates a hidden input element: Sometimes we just need to get the CSRF token without anything else. To get only the CSRF token with no HTML in Django to use in a meta tag .etc call csrf_token like this:
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.
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.
The CSRF token
only ensures that only forms that have originated from trusted domains can be used to POST data back. So it doesn't validate the data or how much data the form sends but if data comes from a form from a legit domain (your site usually). Hence the name: Cross Site Request Forgery protection.
From the docs:
The CSRF token is changed each time a user logs in.
“Stealing” or modifying your own token using Firebug, Chrome dev tools, etc. isn’t a vulnerability.
An attacker cannot steal a user’s browser’s CSRF cookie.
If someone has access (through an man-in-the-middle attack or xss) to your csrftoken
cookie, then this is a vulnerability:
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With