5 ms·
From memory when this came up, I think the concern is someone spoofing a non-HTTPS version of your site to trick a browser into posting to the HTTPS version? So
by ubercore 10y ago
From memory when this came up, I think the concern is someone spoofing a non-HTTPS version of your site to trick a browser into posting to the HTTPS version? Someone that understands this stuff properly will need to chime in.
- r1ch 10y agoIt looks like Django relies on client-side tokens embedded in cookies for CSRF protection, there is no server-side state that the attacker has to guess. A MITM can trick someone to visit http://example.com/ http://example.com/, set their own token in a HTTP cookie for example.com, use the same token in the POST request to https://example.com https://example.com and it will pass validation, as cookies set over HTTP are still sent to HTTPS. Should be easy to mitigate this by using server-side CSRF state, or signing the tokens.
- berdario 10y agoI'm a bit confused... I thought that Django always signed the CSRF tokens with the app's SECRET_KEY But upon looking at the code, it seems that the SECRET_KEY is only used to reseed the PRNG O_o https://github.com/django/django/blob/stable/1.10.x/django/utils/crypto.py#L54-L77 https://github.com/django/django/blob/stable/1.10.x/django/u...
- ubercore 10y agoSecret key is used for signing. https://github.com/django/django/blob/master/django/core/signing.py#L156 https://github.com/django/django/blob/master/django/core/sig...
- abeyer 10y agoUnfortunately the csrf implementation doesn't use that. (At least not in the absence of a session store.) It "encrypts" the random token by adding a random salt to it, but has no way of validating that after generation. When a csrf protected request is made the token in the cookie is compared to the token in the POST data, but not validated in any other way. https://github.com/django/django/blob/master/django/middleware/csrf.py#L50 https://github.com/django/django/blob/master/django/middlewa... I wonder how much of this is just a political issue about the core/contrib division and the fact that csrf is in core while sessions is in contrib. It seems to me that the "right" fix is to make csrf protection require a session store, and move (at least) the signed cookie session support into core. Edit: Actually it looks like cookie signing is already implemented in core, so now I'm really unsure why csrf isn't using that already.
- berdario 10y agoYeah, weird... I guess that since sessions are enabled by default, they didn't bother making it independent/explicitly requiring it
- ubercore 10y agoI think this choice was made because Django doesn't _require_ sessions to be used. So they're making a compromise that could (however marginally) improve security regardless of the configuration of the site. I think perhaps some way of saying "I use sessions, and therefore CSRF should rely on that" could be reasonable, but with security stuff like this I'm really hesitant to say that more definitively.
- abeyer 10y ago"there is no server-side state that the attacker has to guess" That part is certainly true when django isn't using sessions. I think that in normal use the tokens are still always generated on the server, not the client, though. The problem is that like you said, there is no way to validate that without some server state, so even though the server is expected to have generated the token, it can't distinguish and invalidate a token generated by anyone else as long as it's in the correct format.
- berdario 10y agoLooks like it https://security.stackexchange.com/questions/96114/why-is-referer-checking-needed-for-django-to-prevent-csrf https://security.stackexchange.com/questions/96114/why-is-re... I don't think that the solution can be as simple as: > you should not post from HTTP to HTTPS anyway. because if the attacker is MITM'ing your user, he can supply the user a HTTP page that you never created (unless you have HSTS enabled) The obvious inquire: "why doesn't the attacker simply steals the login cookie?", can probably be simply explained if your service is setting the Secure flag in the Set-Cookie header (as it should)... this way, even if the victim is logged in, the attacker wouldn't be able to steal the cookie
- marcosdumay 10y agoI don't think that "the site does not work while somebody is phishing my connection" is a valid complaint. One should indeed protect against malicious HTTP pages, HSTS is a good thing, browser warnings on HTTP is an even better thing. But there is no reason to put any effort on avoiding a 403 error on those cases.
- anderskaseorg 10y agoYou misunderstand the problem. Referer is checked to prevent forged POST requests from HTTP to HTTPS, not to avoid a 403 error.
- marcosdumay 10y agoMy point is that you should never POST from HTTP to HTTPS. So anytime that this happens, Django developers are more than justified on issuing any error they want and marking them wontfix as they wish.