I have the following setup:
- ReactJS PWA frontend application that uses service workers to cache the source code to the client.
- ExpressJS Reverse Proxy which relays any request that would go to a backed API. This handles a login process and stores a token on the server and sends a session cookie to the client. The cookie is HtttpOnly, SameSite, Secure and signed. The proxy also checks if the connection is secure, referrer is in white list and exact match and same for the host.
- Backend API is on a different server with OAuth login protection.
Express returns a server side rendered page on the first load then ReactJS hydrates that page and uses as an SPA. Every file afterwards is cached into the browser.
Every request that comes from the client app is handled with the same token as they are not user specific operations. User specific operations require e-mail and password to get a new unique token from the API.
My issue is: An attacker could create a cookie and send it along with a curl request to the proxy. This would by pass my ReactJS app as both referrer and host can be faked.
I would like to find out how can is secure the connection between the ExpressJS proxy and the ReactJS PWA.
I was thinking about CSRF with csurf but that would not work. If the PWA is installed on a phone's as an app, then it would only access the Proxy when the request is sending. Therefore I cannot set the CSRF header.
If I was to add the CSRF token to the very first request when the client hits the server and the page is rendered with SSR, I would only set the token only once, which can be re used as many times as the attacker wants.
Is there a proper way to lock the proxy to the app somehow?
I cannot store anything in Local storage and I cannot hard code tokens into the source code of the app. (They are insecure options)
Thanks!