Does the CSRF security token provide security?

Django comes with CSRF middleware protection that generates a unique token for each session for use in forms. It scans all incoming POST requests for the correct token and rejects the request if the token is missing or invalid.

I would like to use AJAX for some POST requests, but the requests mentioned do not have an available CSRF token. Pages do not have <form> elements, and I do not want to stir up the markup by inserting a token into a hidden value. I believe that a good way to do this is to set vew to /get-csrf-token/ in order to return the user token based on the cross-site scripting rules of the browser to prevent unwanted sites from requesting it.

Is that a good idea? Are there better ways to protect against CSRF attacks while resolving AJAX requests?

+15
security ajax django csrf
Sep 27 '08 at 23:11
source share
3 answers

If you know that you need a CSRF token for AJAX requests, you can always embed it in HTML; then you can find it through Javascript by going through the DOM. Thus, you will still have access to the token, but you will not open it through the API.

In other words: do it through Django patterns - not through the URL manager. It is much safer.

+11
Sep 28 '08 at 1:36
source share

UPDATE : the below was true and should be true if all browsers and plugins were implemented correctly. Unfortunately, we now know that this is not the case, and that some combination of browser plug-ins and redirects may allow an attacker to provide arbitrary headers in a cross-domain request. Unfortunately, this means that even AJAX requests with the heading "X-Requested-With: XMLHttpRequest" should now be protected by CSRF. As a result, Django no longer exempts Ajax requests from CSRF protection .

Original answer

It should be noted that protection of AJAX requests from CSRF is not needed, because browsers do not allow AJAX requests at different sites. In fact, Django CSRF middleware now automatically frees AJAX requests from scanning CSRF tokens .

This is only valid if you are actually checking the server side of the X-Requested-With header for the value "XMLHttpRequest" (which Django does) and freeing the real AJAX requests from the CSRF scan.

+16
Feb 10 '09 at 17:55
source share

Cancel it, I was wrong. (See Comments.) . You can prevent exploit by ensuring that your JSON follows the specification: always make sure you return the object literal as a top-level object. (I cannot guarantee that there will be no further exploits. Imagine that the browser provides access to the damaged code in its window.onerror event!)

You cannot rely on cross-site scripting rules to keep AJAX responses private. For example, if you return the CSRF token as JSON, the malicious site may override the String or Array constructor and request a resource.

bigmattyh is correct: you need to embed the marker somewhere in the markup. Alternatively, you can reject any POST that do have a referent that does not match. This way, only people with over-the-top software firewalls will be vulnerable to CSRF.

0
Sep 28 '08 at 17:58
source share



All Articles