CSRF Tokens: Preventing Unwanted State Changes on Your Behalf
CSRF protection prevents a malicious site from forcing a user's browser to submit unwanted requests to your app. It adds a unique token to forms that the server validates. The footgun is failing to protect all state-changing endpoints, not just POST forms.
WHY IT EXISTS: Browsers automatically include cookies, including session cookies, with every request to a domain. A Cross-Site Request Forgery (CSRF) attack exploits this by tricking a logged-in user into visiting a malicious page. That page can contain a hidden form that submits a request to your app, and because the browser attaches the user's session cookie, your app treats the forged request as legitimate.
THE MENTAL MODEL: Think of a CSRF token as a secret handshake for your web forms. When a user loads a page with a form, the server gives them a unique, temporary secret (the token) to include with their submission. When the form is submitted, the server checks if the secret handshake matches. A malicious site doesn't know the secret, so any forged request it sends will be rejected, even if the user is authenticated.
HOW IT WORKS: The csurf middleware for Express.js implements this protection. It typically uses the Synchronizer Token Pattern, where a unique token is generated on the server, stored in the user's session, and also embedded in the HTML form. When the form is submitted, the server compares the token from the form with the one in the session. If they match, the request is valid. Alternatively, it can use the Double Submit Cookie pattern, where the token is stored in a cookie instead of the session, reducing server-side state.
WHEN TO USE IT: Use CSRF protection for any request that can change application state on behalf of a user. This includes form submissions via POST, PUT, or DELETE methods that modify data, like updating settings, posting a message, or making a purchase. It is a fundamental security layer for traditional web applications that use cookies for session management.
WHEN NOT TO USE IT: CSRF protection is generally not needed for APIs authenticated with tokens (like JWTs) sent in an Authorization header, as browsers don't automatically attach these headers to cross-site requests. It is also unnecessary for requests that do not modify state, such as GET requests that only retrieve data.
ONE CANONICAL EXAMPLE: In a classic Express.js app, you add the csurf middleware after your session middleware. In the route that renders a form, you generate a token: res.render('settings', { csrfToken: req.csrfToken() });. In the HTML, you include it as a hidden input: <input type="hidden" name="_csrf" value="<%= csrfToken %>">. The middleware then automatically validates this token on the subsequent POST request. Note that the csurf package itself is now archived and no longer maintained; modern frameworks often provide their own built-in CSRF protection mechanisms.
Read the original → github.com
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.