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:
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
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
It is a design weakness of cookies that an application cannot tell whether the cookies were originally set with matching
secure properties, and that if two same-name cookies are set with differing
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.