Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

Django sets a CSRF protection token on the user's machine via a cookie. It then asks for the token on POST requests. If these two don't match, it returns a 403.

If I change manually both the cookie and the token value I send in the request, the request is accepted. Django does not verify that the token value was set by the server. As long as cookie and request match, it won't return a 403.

This doesn't seem safe. What if another website spoofs my domain and set a new cookie and then sends the CSRF token value of the new cookie in the request? Django will compare the two and consider the request legit.
Are they any packages that implement this differently or am I missing something?

share|improve this question
    
That's quite a cool finding! Why don't you validate your proposed exploit and file a bug report? –  scuzzy-delta Dec 17 '13 at 19:54
    
I'm not sure it's something new. It looks like they're implementing a Session-Independant Nonce (cf page 5 seclab.stanford.edu/websec/csrf/csrf.pdf) in which case that is a known security flaw of this implementation. –  Youcha Dec 17 '13 at 20:09
add comment

2 Answers

up vote 9 down vote accepted

Django is using a Double-Submit Cookie and it is accepted as a safe method of CSRF prevention. Why? Because, It is impossible for an attacker to control the cookie filed in a CSRF attack. A CSRF attack is relying on the fact the browser manages cookies, and will include cookies associated with a target domain to the forged HTTP request. It is possible to read and modify the non-HTTPOnly cookies using XSS, however, almost all Anti-CSRF measures can be undermined by XSS.

To answer your question:
Yes, Django's CSRF protection system will prevent a CSRF attack from succeeding, so as long as the application isn't vulnerable to XSS.

share|improve this answer
add comment

Django's CSRF protection is not broken per se; it is generally considered sufficient for many applications.

But indeed the 'double-submitted cookie' model means that CSRF protection will fail in the case an attacker can plant a cookie on a user's browser: the attacker could set the cookie and then immediately submit a form with the same value in its token field. This means there is a potential escalation route from cookie forcing to CSRF, and this can be unacceptable for more security-critical applications.

Cookie forcing is not generally a simple attack in itself. The same-origin policy should normally prevent an attacker site from setting a cookie on another site. If the target site has an XSS flaw then obviously you can set/get cookies, but then if you have XSS you have already lost so badly there is no point worrying about CSRF.

Where this can fall down is hosting factors that may be out of your control as an application author:

  1. When your site is on HTTPS and the attacker has man-in-the-middle against a user. Although they cannot spoof your HTTPS website, they can direct the user to an HTTP address on the same hostname, and from there write a cookie that will be sent by the browser to your HTTPS site later. (This can be somewhat mitigated using the Strict-Transport-Security header.)

  2. If your site is on a.example.com and there is another application running on b.example.com that is vulnerable to XSS, that application could be abused to set a cookie on all of example.com, which would then be sent by the browser to your app at a.example.com.

It is a design weakness of cookies that an application cannot tell whether the cookies were originally set with matching domain and secure properties, and that if two same-name cookies are set with differing domain/secure the results are essentially undefined.

The 'synchroniser token' and 'encrypted token' (HMAC) approaches include a server-side secret unknown to the attacker that prevents the escalation from cookie forcing to CSRF.

Unfortunately Django doesn't lend itself to clean substitution of shared functionality. To improve or replace the CSRF mechanism without breaking all the apps that rely on it involves a bunch of ugly monkey patches.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.