Been wondering something for the past 2 days and i figured coming here to ask would be faster, I’m building a new app that imply auth and while in the past everything i did was on a fullstack django this project is including an external frontend (it runs with Nuxt so it has SSR).
To protect my unauthenticated POST requests I use the default django CSRF protection with a get_token view that gives both a token and a cookie to the frontend. I also edited the settings to provide specific domains for the cookie and trusted hosts for the tokens and in my testing it does seem to do it’s job pretty well.
I also added another layer of protection (that i deem to be overkill) which is that the view that generate the token for the front is only called on it’s SSR + has an unique regenerated token (token’s TTL is a week) so even if you somehow get the view url it is impossible to call it without that private token.
But even with all of this i am still wondering if it’s possible to “spoof” the CSRF protection by extracting the cookie and the token that the website provide on the client and send POST requests considered valid.
I know that this is probably a non-issue since if it was that easy to spoof then even fullstack django would suffer from it but figured I would still ask.
I think you need to keep in mind what specific attack you are protecting against. CSRF is a very specific case where a user is logged into a site A, and then a site B is POST:ing to A to do malicious stuff. The CSRF protection in Django will cover this, and only this. And only if the CSRF token cannot be extracted from site B via javascript.
You’re right I think I’m overthinking it. It’s just that I’m concerned about the fact that the project’s auth flow is fully open to unauthenticated requests. Since the frontend is an SPA, I can’t really protect everything behind SSR and some steps of the auth are fully exposed if you know what request to do. I was mainly wondering if the CSRF protection could prevent POSTs from a third party site.
Unauth as guest user, with no session. And open as for exposed views, like for example imagine you get on a form asking you for your email adress and then it switch to another form asking for your password, normally I would rebuild the page server side when you enter the mail and redirect to a new page asking for the password, so nothing is “exposed” it’s fully server side, using an external frontend forces me to expose the views so on the SPA you enter your email and it does an api request that just return if you have to enter your password etc. Basically every request required by the auth flow becomes exposed and easy to redo for anyone.
I think you’re overthinking this also. It doesn’t become more or less secure if the login flow is split into parts with one part restricted by a session. In fact, don’t do that, it makes login slower and breaks password managers
Front request a view that return if the account exist or no
If the account exist show the new email/password form with email already entered and then allow login.
Else send an email with an OTP and request it on the front, if the OTP is verified then show registration form
Allowing anyone to check if a certain email is registered is a slight lowering of security. And also, again, worse UX than having just a single page with email+password on the same page.
I know it’s fashionable to split that into two pages nowadays, but think about what the tradeoff is? An extra click is the best case, and what did you gain?
I need to give it a though cause there’s some internal stuff that were favorable for this flow, i could probably make a normal login form and keep a single email field for the registration to fix it but eh, not sure for now.
anyways thanks for your time, I’ll try to overthink less, but I just want to do things the right way