-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSRF and SSR #417
Comments
Historically, most websites have exclusively used server side rendering with authentication. Session Tokens are typically stored in cookies. To best protect against session hijacking (e.g. from third party JavaScript in advertising, tracking, browser extensions, XSS) these should be server only readable cookies that are not accessible directly from JavaScript. This is the model NextAuth.js uses.
If a user is signed in, any request from the client will have a secure, sever only readable cookie set that can be used to either look up a session in a database (if it is a database session token) or decoded and verified (if it is a JSON Web Token) to identify the user.
Using server readable only cookies is secure without a CSRF token. The double submit cookie method for cookies used by NextAuth.js is documented by OWASP, and includes protections such as a cookie prefix and cookie signature to ensure it has not been forged. It might be helpful to give an example of a flow you think is "insecure", and to stick to the question template (which is tended to help us help you) to understand what you are trying to do and give context.
Are you asking what is the point of server side rendering in general, or the point of Next.js over Create React App, or is this specific question in relation to authentication? |
Thank you for taking the time to answer my question in such detail. I have been thinking and considering SSR for a while and always came to the conclusion, that it is fundamentally insecure. It looks like it is only "a little insecure". So GET requests can be forged (by using a special image tag) and will retrieve user specific data from the user. However the attacker cannot use this data as it is not available to the javascript on the attackers website. If the GET request would execute any kind of transaction, the attack would be possible. See also owasp on this. Correct CORS headers will prevent forged POST requests, so these can be used for transactions safely. It is important to note that SSR is only secure if:
Further: For me personally this feels like juggling with jigsaws. Especially in the context that a lot of users of next.js etc. are pretty newby and are possibly tempted to accept some query params in the GET routes to trigger a transaction "for convenience" (I mean their basic entrypoint for any kind of example is a "page" which is only accessible via GET). I will potentially also in the future use client side rendering with JWTs in local storage because this approach is dead simple. Even if one triggers transactions with GET one is safe against CSRF. Thank you again @iaincollins for coming back on this and I think this issue can be closed as "something mildly interesting for people to read in the future". *How often have I seen the advice to set CORS-Headers to allow "*" to be able to develop locally, etc. |
And just to spare some time: I know that malicious javascript on my site can steal the JWT from the local storage. But if one has malicious javascript on a website, the attacker can do everything with or without the JWT (for example execute arbitrary authenticated requests) no matter what authentication method is used. |
And one little joke, if you do not mind:
Historically, most websites have been insecure... |
It sounds like you are unfamiliar with some of the established conventions for HTTP (how GET is used vs POST/PUT/DELETE), how cookies are used in authentication flows (httpOnly, cookie prefixes), what CSRF tokens are for (and how they should be used) and what the pitfalls of client side session state are (e.g. session hijacking via XSS / domain attacks). It is absolutely not true that server side authentication is less secure than client side authentication - particularly with regard to protection against session hijacking (e.g. from XSS, third party trackers, advertising code, etc). I just want to be very clear and set the record straight on that to avoid any contention in future. |
I do not understand how SSR could work with (secure) authentication. With the initial GET request, I cannot use authentication headers because they wont be sent if I do not query from Javascript so I have to use cookies. But using cookies is insecure as long as I do not have CSRF-protection via a CSRF-token which is not stored as a cookie, but has to be set and send via Javascript. So how can I securely return user specific content on the initial GET request?
So my expectation is that first just some JS ist returned which then fetches the private data from the client. Everything else looks insecure to me. Maybe I am missing something but if not the full html is returned on the initial request, what is the point of using next.js in the first place instead of cra?
The text was updated successfully, but these errors were encountered: