@fastify/csrf-protection

Sync Token Pattern for Form Apps

@fastify/csrf-protection

For cookie-based session apps, @fastify/csrf-protection issues a token the browser must echo back on mutating requests, blocking cross-site form forgery.

4 min read Level 2/5 #fastify#csrf#security
What you'll learn
  • Install @fastify/csrf-protection alongside cookies or sessions
  • Issue a token on GET
  • Verify tokens on POST, PUT, and DELETE

CSRF only matters when authentication is automatic — cookies and Basic Auth. If you carry a Bearer token in JS, attackers cannot forge requests cross-site. For form apps, you need a synchroniser token.

Install & Register

npm install @fastify/csrf-protection @fastify/cookie
import cookie from '@fastify/cookie'
import csrf from '@fastify/csrf-protection'

await app.register(cookie)
await app.register(csrf, { cookieOpts: { signed: true } })

Issue a Token

Expose an endpoint your client can call to get a fresh token:

app.get('/csrf', async (req, reply) => {
  return { token: reply.generateCsrf() }
})

The token is signed and stored in a cookie; the value is returned to the client to echo in a header or hidden field.

Verify on Mutating Routes

app.post(
  '/transfer',
  { preHandler: app.csrfProtection },
  async (req) => {
    // ... handler runs only if the token verifies ...
    return { ok: true }
  },
)

If the token is missing or wrong, the request is rejected with 403 before your handler runs. Apply it globally to all mutating routes — or to a route prefix.

@fastify/helmet →