Remix Utils - v9.1.0
    Preparing search index...

    Module Middleware/CSRF-Token

    The CSRF Token middleware protects your application from Cross-Site Request Forgery attacks by using a token-based approach where a random token is stored in a cookie and must be included in form submissions.

    Note: This depends on @oslojs/crypto, @oslojs/encoding, and React Router.

    import { createCsrfTokenMiddleware } from "remix-utils/middleware/csrf-token";
    import { createCookie } from "react-router";

    let cookie = createCookie("csrf", {
    path: "/",
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
    sameSite: "lax",
    });

    export const [csrfTokenMiddleware, getCsrfToken] = createCsrfTokenMiddleware({
    cookie,
    });

    To use it, you need to add it to the middleware array in your app/root.tsx file.

    import { csrfTokenMiddleware } from "~/middleware/csrf-token.server";
    export const middleware: Route.MiddlewareFunction[] = [csrfTokenMiddleware];

    Use the getCsrfToken function in your root loader to retrieve the token and pass it to your forms:

    import { getCsrfToken } from "~/middleware/csrf-token.server";

    export async function loader({ context }: Route.LoaderArgs) {
    let csrfToken = getCsrfToken(context);
    return { csrfToken };
    }

    You can use this with the AuthenticityTokenProvider and AuthenticityTokenInput components from remix-utils/csrf/react:

    import { AuthenticityTokenProvider } from "remix-utils/csrf/react";

    export default function App({ loaderData }: Route.ComponentProps) {
    return (
    <AuthenticityTokenProvider token={loaderData.csrfToken}>
    <Outlet />
    </AuthenticityTokenProvider>
    );
    }

    Then in your forms:

    import { AuthenticityTokenInput } from "remix-utils/csrf/react";

    function MyForm() {
    return (
    <Form method="post">
    <AuthenticityTokenInput />
    </Form>
    );
    }

    The middleware will automatically validate the token on non-safe requests (POST, PUT, DELETE, PATCH) and reject requests with invalid or missing tokens with a 403 Forbidden response.

    You can customize the middleware behavior:

    let [csrfTokenMiddleware, getCsrfToken] = createCsrfTokenMiddleware({
    cookie,
    // The name of the form field containing the token (default: "csrf")
    formDataKey: "csrf",
    // A secret to sign the token for extra security
    secret: process.env.CSRF_SECRET,
    // Custom handler for invalid tokens
    onInvalidToken(error, request, context) {
    return new Response("Invalid CSRF token", { status: 403 });
    },
    });

    You can allow cross-site requests from specific trusted origins to bypass token validation:

    let [csrfTokenMiddleware, getCsrfToken] = createCsrfTokenMiddleware({
    cookie,
    origin: "https://trusted.com",
    });

    Or using a RegExp for pattern matching:

    let [csrfTokenMiddleware, getCsrfToken] = createCsrfTokenMiddleware({
    cookie,
    origin: /\.trusted\.com$/,
    });

    Or using an array of strings and RegExps:

    let [csrfTokenMiddleware, getCsrfToken] = createCsrfTokenMiddleware({
    cookie,
    origin: ["https://trusted1.com", "https://trusted2.com", /\.trusted\.com$/],
    });

    Or using a function for dynamic validation:

    let [csrfTokenMiddleware, getCsrfToken] = createCsrfTokenMiddleware({
    cookie,
    origin: async (origin, request, context) => {
    return await checkOriginInDatabase(origin);
    },
    });

    Note: If you add this middleware to the root route, it will apply to every route in your application. If your app has API routes that should accept cross-site requests (e.g., for webhooks or third-party integrations), you should move the CSRF middleware to a layout route that wraps only your UI routes, leaving API routes unprotected by CSRF validation.

    Namespaces

    createCsrfTokenMiddleware

    Functions

    createCsrfTokenMiddleware