Cross Site Request Forgery (CSRF)

Optional Protect user actions from unwanted state change.


Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they’re currently authenticated. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker’s choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application.

ℹ Read more about CRSF here.

This functionality is based on the great module by Morgan. You can check out the full documentation and reference here

nuxt-csurf is disabled by default but you can enable it with default configuration like following:

nuxt.config.ts
export default defineNuxtConfig({
  security: {
    csrf: true
  }
})

Now, you can use the auto-imported composables for handling CRSF:

// Wrapper around `useFetch` that automatically adds CSRF token in headers
const { data, pending, error, refresh } = useCsrfFetch('/api/login', { query: 'value1' })

// Have access to the CSRF token value
const { csrf } = useCsrf()

Apart from just enabling it, you can pass a custom configuration to the underlying nuxt-csurf module by using the following interface:

interface ModuleOptions {
  https?: boolean,
  cookie?: CookieSerializeOptions,
  cookieKey?: string,
  methodsToProtect?: Array<string>, // the request methods we want CSRF protection for
  excludedUrls?: Array<string|[string, string]>, // any URLs we want to exclude from CSRF protection
  encryptSecret?: string,
  encryptAlgorithm?: string
}

interface CookieSerializeOptions {
  domain?: string | undefined;
  encode?(value: string): string;
  expires?: Date | undefined;
  httpOnly?: boolean | undefined;
  maxAge?: number | undefined;
  path?: string | undefined;
  sameSite?: true | false | 'lax' | 'strict' | 'none' | undefined;
  secure?: boolean | undefined;
}

Using with tRPC Nuxt

TRPC uses POST requests for the mutation endpoints. Using the CSRF protection functionality of this module with trpc-nuxt will help you protect your mutation endpoints from CSRF.

In order to make the CSRF functionality of this module work with trpc-nuxt, we have to add the CSRF token value into a csrf-token header inside the outgoing request headers in our trpc client.

import { createTRPCNuxtClient, httpBatchLink } from "trpc-nuxt/client";
import type { AppRouter } from "@/server/trpc/routers";

export default defineNuxtPlugin(() => {
  const headers = useRequestHeaders();
  const { csrf } = useCsrf();

  const client = createTRPCNuxtClient<AppRouter>({
    links: [
      httpBatchLink({
        // Headers are called on every request
        headers() {
          // Add CSRF token to request headers
          return { ...headers, "csrf-token": csrf };
        },
      }),
    ],
  });

  return {
    provide: {
      client,
    },
  };
});