JAVASCRIPT
Implementing CSRF Protection with Anti-CSRF Tokens
Learn to implement robust Cross-Site Request Forgery (CSRF) protection in a Node.js Express application using the `csurf` middleware to generate and validate anti-CSRF tokens.
const express = require('express');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const csrf = require('csurf');
const app = express();
// Middleware setup
app.use(cookieParser());
app.use(session({
secret: 'your_session_secret',
resave: false,
saveUninitialized: true,
cookie: { httpOnly: true, secure: process.env.NODE_ENV === 'production' }
}));
// CSRF middleware
const csrfProtection = csrf({ cookie: true });
// Apply CSRF protection to routes that modify state
app.use(csrfProtection);
// Expose CSRF token to views (e.g., for forms)
app.use((req, res, next) => {
res.locals.csrfToken = req.csrfToken();
next();
});
// Example form route
app.get('/form', (req, res) => {
// In a real app, render an HTML form with a hidden input for csrfToken
res.send(
`<form action="/process" method="POST">
` +
` <input type="hidden" name="_csrf" value="${res.locals.csrfToken}">
` +
` <input type="text" name="data">
` +
` <button type="submit">Submit</button>
` +
`</form>`
);
});
// Example processing route (POST request)
app.post('/process', (req, res) => {
// If the token is valid, req.body will be available
res.send('Form submitted successfully with CSRF protection!');
});
// Error handling for CSRF issues
app.use((err, req, res, next) => {
if (err.code === 'EBADCSRFTOKEN') {
res.status(403).send('Invalid CSRF token.');
} else {
next(err);
}
});
app.listen(3000, () => console.log('Server listening on port 3000'));
How it works: This snippet shows how to integrate `csurf` middleware in an Express application to protect against Cross-Site Request Forgery (CSRF) attacks. It generates a unique, secret token for each user's session and expects this token to be submitted with state-modifying POST requests. The `csurf` middleware automatically validates this token, rejecting requests without a valid one. The token is exposed to views (`res.locals.csrfToken`) so it can be included as a hidden field in HTML forms.