CSRF functionality in Redwood

Hi @dthyresson It s good to hear from you.

Actually, the main middleware I am looking for is one that implements the CSRF protection. I used these two Express middleware before and they are proven middlewares.

The cookie-parser middleware must be placed before csurf. And what csurf does is the following: Creates a CSRF token and validates an incoming request against that token. This middleware adds a req.csrfToken() function to make a token which should be added to requests which mutate state, within a hidden form field, query-string etc. This token is validated against the visitor’s csrf cookie.

I need to protect almost all GraphQL endpoints including login and register.

According to my opinion, this token should be issued when a user requests the index.html (JAM stack, residing somewhere in CDN) for the first time. Now for all subsequent requests, the client sends the CSRF token with all requests.

How can we implement this in Redwood. Kindly tell me. Thanks.

As a side note, Fastify allows us to use the Express middleware. Also, the Express middleware are simply functions.

It’d be great if the Redwood uses these two middleware functions to provide the CSRF functionality out-of-the-box.

@ramandhingra I just want to make sure you are aware of a few things:

I need to protect almost all GraphQL endpoints including login and register.

Redwood does this via the @requireAuth directive automatically. Though maybe you are creating som custom authentication scheme?

Redwood enforces auth using an envelop plugin for the graphQL server, see here: redwood/packages/graphql-server/src/plugins/useRedwoodAuthContext.ts at main · redwoodjs/redwood · GitHub

The key point is to:

extendContext({ currentUser })

such that the api side global context will have a currentUser set.

Perhaps you will want to create you own custom plugin to handle your auth case?

In here you can fetch the cookie for the event headers and authenticate as needed.

Slight correction: CSRF is only half-done in dbAuth—I couldn’t figure out where to add arbitrary headers (like a csrf-token header) to every GraphQL request, including those for currentUser. There’s an open issue here: https://github.com/redwoodjs/redwood/issues/3075

I wasn’t aware of that since I don’t often use dbAuth in my apps, but I added some ideas of how you might accomplish tis to the issue

Okay fine. Just to make sure, Fastify is used when we deploy an app on AWS. And for this purpose, you wrote the following. Am I right?

Storing a CSRF token in the db means that we need to hit the db everytime a resolver is executed. The CSRF protection can be implemented in a stateless manner too. As stated in the following link, there is a double submit cookie pattern for the same.

The next-auth also uses the same method. It is stated in this Readme
https://github.com/nextauthjs/next-auth/blob/main/docs/docs/getting-started/rest-api.md

As stated above, CSRF protection is not actually implemented in dbAuth yet. But, even when it is, CSRF tokens will not be stored in the database, they’re implemented as request headers combined with a token encrypted into your auth session cookie.

@rob

CSRF in dbAuth (database) made me assume that they are getting stored in db. If possible, use the csurf and cookie-parser modules to implement it. These modules further use several other modules to make CSRF work perfectly.