Django CSRF Bug

en in code • 2 min read

We had this problem: our application worked well on the desktop but on phone any action had CSRF problem.

Mm, strange. Soon we discovered it’s problem only with Android. Later we were sure it’s only Chrome on Android. Even stranger!

Next step we did was to check what we are using exactly for CSRF validation. Django. Without customization. Of course, no one had this issue by checking Google, so it had to be some problem with our configuration. But it worked everywhere else…

We found that same cookie was used for our top domain and our application runs on sub-domain. It could be an issue, all browsers can handle it but Chrome on Android has some problem with that, we thought. We changed it. Deployed it. And nothing!

Ok, time to plug the phone and open debug tool to see what’s happening. In a development environment, everything worked just fine. That’s very strange and because of that, we were still checking the configuration for a few more minutes. Without success.

After an hour or so we noticed that token was really wrong. The token in response from the server was different than which was then set up to the session. We didn’t know what to check next so we did the worst thing possible. Add some logging on the server and see what’s happening. We noticed some regeneration of token. Why it’s regenerated? And why there is more than one request when using phone?!

And then we finally saw it. Android is doing one request for a page user wants and one for some special 96px version of an icon it could be used… somewhere. Which generates 404 page and we have some form on every page. But Django (it took us another half an hour, probably more) doesn’t use CSRF middleware for 404 and 500 pages! Which means Django is not going to take the token from a cookie and when the token is needed, a new one is generated!

Fix is to use a decorator for 404 and 500 views, as described in Django documention. It’s there, but who would expect that.

Half of the day. We spent half of the day, two of us, to figure out this issue. I really don’t know how to explain to people why the development of simple websites cost so much money. Better to just laugh, take a glass of whisky and watch Django Unchained. Much more fun than debug Django app. :-P






2 responses

I wonder why Django keeps only the last generated token instead of a few last ones... I don't see the security improvement at all, only failed requests. I have really no idea. I would appreciate that functionality.




You may also like

en Makefile with Python, November 6, 2017
en Fast JSON Schema for Python, October 1, 2018
en Deployment of Python Apps, August 15, 2018
cs Jasně, umím Git…, August 6, 2014
cs Checklist na zabezpečení webových aplikací, March 1, 2016

More posts from category code.
Do not miss new posts thanks to Atom/RSS feed.



Recent posts

cs Zubní pohotovost, October 19, 2021 in family
en Dancers Are Not Deaf (Yet), October 12, 2021 in dance
cs Je dobré mýti Matýska, October 4, 2021 in family
cs Jsem levák…?, September 21, 2021 in family
en Human Evolution of the Past and Future, September 14, 2021 in humanity