0

What would be the recommended way (simple, and secure) to initialize CSRF token when working with Single Page Applications?

I have figured out some possible solutions but all of them have some downsides:

a) Before login or any request, create CSRF request to obtain a token.

  • Downside: The Client/frontend should implement logic to request CSRF if it is missing

b) Exempt login request from CSRF protection and initialize token on every login

  • Downside: Is it safe to exempt login from CSRF protection?
  • If using multiple endpoints and Single Sing On, we still need to init CSRF token in every endpoint

c) Init CSRF token when the client request a frontend code (on SPA load / refresh)

  • Downside: Complex logic and extra request to backend needed in frontend providing endpoint
  • If we use multiple endpoints and can not validate the same CSRF tokens in every endpoint we do not know where to init the token
Viljami
  • 639
  • 7
  • 15
  • Regarding b), login endpoints can also deserve CSRF protection, see [here](https://stackoverflow.com/questions/75195551/should-csrf-protection-token-be-given-before-authenticating). Regarding c), your backend does not need CSRF protection if it is only called by the frontend server, see [here](https://stackoverflow.com/questions/74844997/csrf-tokens-with-separate-api-and-web-server). – Heiko Theißen Jan 28 '23 at 16:31
  • Thanks @HeikoTheißen . I have to do some extra research with your point related to b). Related to c) I think you misunderstood my architecture. The client / browser is directly connecting with my backend API. When working with single page applications, on page refresh, the JS code is loaded from the frontend server to the client browser. Then client starts communicating with backend server. So the idea of c) was, that frontend server init CSRF token (maybe fetch it from the backend server) and add it into client cookies. This would happen in every page refresh . – Viljami Jan 30 '23 at 08:29
  • So related to b), the login request should also being protected with CSRF token, good discussion about the topic in [this](https://stackoverflow.com/questions/6412813/do-login-forms-need-tokens-against-csrf-attacks) answer. – Viljami Jan 30 '23 at 08:50

1 Answers1

0

The current solution/answer to this problem is the following:

  1. Client sends a CSRF token request
  2. Server adds CSRF token into client cookies
  3. Client sends a login request with his credentials and copies the CSRF token from cookies into headers
  4. Server checks the cookie & header match and processes a login request. The server sets a session cookie and rotates a CSRF token.
  5. Other (login required) endpoints check header & cookie match AND validate session cookie.

When working with multiple endpoints

  • Implement BFF or proxy server which handles the CSRF protection. Allow connections to the server endpoints only from the proxy/BFF server. The endpoints does not need CSRF protection anymore.
  • All requests from Client / browser is routed through the CSRF protected BFF/proxy server.

Pros

  • Login requests are now protected with CSRF
  • If multiple endpoints are needed, only one CSRF token init request must be done.
  • CSRF token is rotated and unique in every new session.

Cons

  • Client/frontend should implement CSRF request logic and missing CSRF token error handling thus increasing the complexity. CSRF token init can not be done silently for example during the login request.
  • When working with multiple endpoints, separate BFF/proxy server is needed.
Viljami
  • 639
  • 7
  • 15