Skip to content

Cross Site Request Forgery (CSRF)

Now that we have routing set up, we need a way to secure our application.

We will start by adding cross-site request forgery CSRF protection to our application.

One way to protect against CSRF attacks is to use a CSRF token.

This is a unique string that is generated for each user session and is sent with each request to the server.

Before processing any request, the server checks that the token is valid and that it matches the userโ€™s session. If it doesnโ€™t, the request is rejected.

Letโ€™s add this now.

Luckily, adding CSRF protection to our application is straightforward.

  1. Open app/root.tsx.

  2. Add the following import to the top of your app/root.tsx file:

    app/root.tsx
    import { type LinksFunction } from '@remix-run/node'
    import Document from '~/components/shared-layout/Document'
    import { useNonce } from '~/utils/nonce-provider.ts'
    import rootLinkElements from '~/utils/providers/rootLinkElements'
    import HeaderWithSearch from './components/organisms/HeaderWithSearch'
    import FooterMenuRight from './components/organisms/Footer/FooterMenuRight'
    import ThemeSwitch from './components/shared-layout/ThemeSwitch.tsx'
    import { loader } from './__root.server.tsx'
    import { Outlet, useLoaderData } from '@remix-run/react'
    import useTheme from './hooks/useTheme.tsx'
    import { AuthenticityTokenProvider } from 'remix-utils/csrf/react'
  3. We simply need to wrap our application with this AuthenticityTokenProvider to ensure that a valid CSRF token is checked for every request across the entire application.

    This is done by wrapping the JSX returned by the App component with the AuthenticityTokenProvider, then passing a csrfToken from the data object to the AuthenticityTokenProvider component:

    app/root.tsx
    export default function App() {
    const data = useLoaderData<typeof loader>()
    const nonce = useNonce()
    const theme = useTheme()
    useToast(data.toast)
    return (
    <AuthenticityTokenProvider token={data.csrfToken}>
    <Document nonce={nonce} theme={theme}>
    <div className="flex h-screen flex-col justify-between">
    <HeaderWithSearch />
    <div className="flex-1">
    <Outlet />
    </div>
    <div className="container flex justify-between pb-5">
    <ThemeSwitch userPreference={data.requestInfo.userPrefs.theme} />
    </div>
    <FooterMenuRight />
    </div>
    </Document>
    </AuthenticityTokenProvider>
    )
    }
  4. Save your changes.

  5. Before moving on to the next tutorial, make sure you rearrange the imports at the top of the app/root.tsx file by using the VS Code keyboard shortcut SHIFT + ALT + O (Windows) or SHIFT + OPT + O (Mac)

Although not much has changed visually, weโ€™ve added a strong security feature to our application that is crucial for you to write about in your assignment.

In the next step, we will secure our application against spambots by adding a โ€˜honeypotโ€™ field to our forms.