rcpch / rcpch-audit-engine

Epilepsy12 Audit Platform
https://e12.rcpch.ac.uk/
GNU Affero General Public License v3.0
5 stars 5 forks source link

CSRF error on /account/login #1020

Open mbarton opened 3 months ago

mbarton commented 3 months ago

Reported via email by @SAbdin93. Customers see an opaque CSRF error message when trying to log in:

Screenshot from 2024-08-13 15-20-17

We can see from the production logs that it happens occasionally and is caused by a mismatch between the CSRF cookie and the hidden token in the login form:

django-1  | 2024-08-09T10:57:09.101654581Z WARNING [django.security.csrf] Forbidden (CSRF token from POST incorrect.): /account/login/
django-1  | 2024-08-09T12:28:34.590409092Z WARNING [django.security.csrf] Forbidden (CSRF token from POST incorrect.): /account/login/
django-1  | 2024-08-09T12:28:43.242638408Z WARNING [django.security.csrf] Forbidden (CSRF token from POST incorrect.): /account/login/
django-1  | 2024-08-09T12:29:07.995986807Z WARNING [django.security.csrf] Forbidden (CSRF token from POST incorrect.): /account/login/
django-1  | 2024-08-09T13:30:36.035838126Z WARNING [django.security.csrf] Forbidden (CSRF token from POST incorrect.): /account/login/
django-1  | 2024-08-09T13:30:41.912459997Z WARNING [django.security.csrf] Forbidden (CSRF token from POST incorrect.): /account/login/
django-1  | 2024-08-12T15:15:45.274644910Z WARNING [django.security.csrf] Forbidden (CSRF token from POST incorrect.): /account/login/

I've verified using the logs that the user reporting the error saw this exact error message as they were then able to log in afterwards.

The error doesn't stop you logging in by opening another tab and trying again. I'm not exactly sure how it happens but I think it's to do with old tabs staying open in the browser. I've been able to reproduce with the following steps:

  1. Log in
  2. Log out and leave the tab open on the login screen
  3. Open a new tab
  4. Log in in the new tab (this rotates the CSRF token, later triggering the error)
  5. Log out
  6. Try to log in using the old tab without refreshing the page

We can't fix this problem per se without custom logic to retry the request with a new CSRF token which defeats much of the point of having it in the first place. I don't think we should remove it as CSRF tokens on login pages are useful in avoiding attacks where users are tricked into logging in to an account that isn't actually their own (see this Stack Overflow thread).

It is quite straight forward though to punt them back to the login form to try again rather than showing a big angry technical error message. See https://forum.djangoproject.com/t/forbidden-csrf-token-from-post-incorrect-accounts-login/19146/1.

eatyourpeas commented 3 months ago

I agree better that than what is happening. I am confused though as we used to have a custom 403 page. I am not clear why at least that is not rendering instead of the django one.

SAbdin93 commented 3 months ago

Thank you for looking into this :) - I will let the Clinicians know.