csrf-middleware Overview
The csrf middleware protects your application against Cross-Site Request Forgery (CSRF) attacks. It uses the double-submit cookie pattern to verify that form submissions and state-changing requests actually originate from your site.
What is a CSRF Attack?
Imagine you are logged into your banking site at https://bank.com. You then visit a malicious page at https://evil.com. That page contains a hidden form:
<form action="https://bank.com/transfer" method="post">
<input type="hidden" name="to" value="attacker" />
<input type="hidden" name="amount" value="10000" />
</form>
<script>document.forms[0].submit()</script>Because your browser automatically attaches your bank.com cookies to any request to bank.com, the bank's server thinks you submitted the form. The transfer goes through. This is a Cross-Site Request Forgery -- the attacker forges a request from your browser to a site where you are authenticated.
How the Middleware Protects You
The csrf middleware uses a technique called the double-submit cookie pattern:
Token generation: When a user visits a page (a GET request), the middleware generates a random token and stores it in the user's session.
Token embedding: You include this token as a hidden field in every form on the page.
Token validation: When the user submits a form (a POST request), the middleware checks that the token in the form body matches the token in the session. If they do not match, the request is rejected with a
403 Forbiddenresponse.
This works because the attacker cannot read the token from your site's session. They can send requests to your site, but they cannot read responses from it (thanks to the browser's same-origin policy). Without the correct token, their forged forms are rejected.
When to Use CSRF Protection
Use CSRF protection when:
- Your application has HTML forms that perform state-changing actions (creating, updating, deleting data).
- You use session-based authentication (cookies).
- Your application is server-rendered.
You may not need CSRF protection when:
- Your API uses token-based authentication (like
Authorization: Bearer ...) instead of cookies -- these tokens are not automatically attached by the browser. - You are using the cop-middleware which provides tokenless cross-origin protection via browser
Sec-Fetch-*headers.
Quick Example
import { createRouter } from 'remix/fetch-router'
import { session } from 'remix/session-middleware'
import { csrf, getCsrfToken } from 'remix/csrf-middleware'
let router = createRouter({
middleware: [
session(sessionCookie, sessionStorage),
csrf(),
],
})
router.get(routes.newPost, ({ context }) => {
let token = getCsrfToken(context)
return html`
<form method="post" action="/posts">
<input type="hidden" name="_csrf" value="${token}" />
<input type="text" name="title" />
<button type="submit">Create</button>
</form>
`
})The getCsrfToken() function retrieves the token from the context so you can embed it in your forms. On POST, the middleware validates it automatically.
Next Steps
- Tutorial: Add CSRF Protection to Forms -- Step-by-step guide to protecting forms and API endpoints.
- API Reference -- Complete documentation of options and behavior.