2.0.0 • Published 8 months ago

@nestjs-kitchen/csrf v2.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

@nestjs-kitchen/csrf

NPM Version NPM License codecov

A CSRF module in NextJS.


Feature

  • ✅ Supports double-csrf validation strategy (cookie-based, stateless)

  • ✅ Supports traditional session-based validation strategy (stateful)

  • ✅ Supports one-time-use CSRF tokens

  • ✅ Compatible with both @nestjs/platform-express and @nestjs/platform-fastify frameworks

Install

$ npm install --save @nestjs-kitchen/csrf

Usage

double-csrf Strategy (Cookie-Based)

This strategy stores the CSRF secret in the cookie and requires cookie support.

For @nestjs/platform-express:

npm install cookie-parser

For @nestjs/platform-fastify:

npm install @fastify/cookie

Example

Register module:

// in app.module.ts

@Module({
  imports: [
    // ...
    CsrfModule.register({
      type: 'double-csrf'
    })
    // ...
  ],
  controllers: [AppController],
  providers: [],
})
export class AppModule {}

Apply CSRF in a Controller:

// in app.controller.ts

import { Controller, Get, Post } from '@nestjs/common';
import { Csrf, CsrfInterceptor, CsrfGuard } from '@nestjs-kitchen/csrf';

@UseGuards(CsrfGuard)
@UseInterceptors(CsrfInterceptor)
@Controller()
export class AppController {

  @Csrf()
  @Post('/require-csrf')
  post(){
    // This handler will only execute if CSRF validation passes
    // ...
  }

  @Csrf.Sign()
  @Get('/csrf')
  csrf() {
    // Generates and stores a new CSRF token (skips CSRF validation)
    return true;
  }
}

session Strategy (Session-Based)

This strategy stores the CSRF secret in the session and requires session support.

For @nestjs/platform-express:

npm install express-session

For @nestjs/platform-fastify:

npm install @fastify/session

Alternatively, for Fastify, you can also use:

npm install @fastify/secure-session

⚠️ Note: When using @fastify/secure-session, one-time CSRF tokens are not supported because secure-session is stateless.

Example

Register module:

// in app.module.ts

import { Module } from "@nestjs/common";
import { CsrfModule } from '@nestjs-kitchen/csrf';
import { AppController } from './app.controller.ts';

@Module({
  imports: [
    // ...
    CsrfModule.register({
      type: 'session'
    })
    // ...
  ],
  controllers: [AppController],
  providers: [],
})
export class AppModule {}

Apply CSRF in a Controller:

Same as double-csrf example.

Options

Common options:

OptionTypeDescriptionDefault
getToken(req: any) => stringFunction to extract CSRF token from the request.(req) => req.headers['x-csrf-token']
headerKeystringResponse header name to expose the CSRF token.'x-csrf-token'
verifyMethodsHttpMethod[]List of HTTP methods that require CSRF validation.['PATCH', 'PUT', 'POST', 'DELETE', 'CONNECT', 'TRACE']
globalbooleanIf set to true, automatically applies CsrfGuard and CsrfInterceptor globally.false

double-csrf options:

OptionTypeDescriptionDefault
type'double-csrf'Strategy type: stores token in cookie only. Requires cookie support.'double-csrf'
cookieKeystringCookie name to store CSRF secret.'_csrf'
cookieOptions.pathstringCookie path.'/'
cookieOptions.securebooleanUse secure cookie (only sent over HTTPS).false
cookieOptions.sameSitestringSameSite policy.'strict'
cookieOptions.httpOnlybooleanWhether the cookie is HttpOnly.true
cookieOptions.signedbooleanWhether the cookie is signed.false
cookieOptions.maxAgenumberCookie expiration.undefined
cookieOptions[...]anyAdditional cookie options.

session options:

OptionTypeDescriptionDefault
type'session'Strategy type: stores token in session. Requires session support.'session'
sessionKeystringSession key to store the CSRF secret.'_csrf'
oneTimeTokenbooleanEnable one-time-use tokens (valid for a single use only).false
oneTimeTokenTTLnumberTTL for one-time tokens in milliseconds.undefined
nonceStore.get(key: string) => any \| Promise<any>Retrieve one-time token from store.In-memory
nonceStore.set(key: string, value: string, ttl?: number) => void \| Promise<void>Store one-time token.In-memory
nonceStore.del(key: string) => void \| Promise<void>Delete one-time token.In-memory

License

MIT License

2.0.0

8 months ago