JAVASCRIPT
Implement CSRF Protection with `csurf`
Implement robust Cross-Site Request Forgery (CSRF) protection in your Node.js Express application using the `csurf` middleware to secure state-changing requests.
const express = require('express');
const cookieParser = require('cookie-parser');
const session = require('express-session'); // Recommended for CSRF tokens
const csurf = require('csurf');
const path = require('path');
const app = express();
// 1. Configure session middleware (required by csurf when using sessions)
app.use(cookieParser());
app.use(session({
secret: process.env.SESSION_SECRET || 'a_very_secret_key_for_dev_only',
resave: false,
saveUninitialized: true,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production', // Use secure cookies in production
maxAge: 3600000 // 1 hour
}
}));
// 2. Configure CSRF protection middleware
const csrfProtection = csurf({ cookie: true }); // Using cookies for token storage
app.use(express.urlencoded({ extended: false })); // For parsing application/x-www-form-urlencoded
// Serve a simple HTML form for demonstration
app.get('/', csrfProtection, (req, res) => {
// In a real app, you'd use a templating engine (e.g., EJS) to inject the token:
// res.render('index', { csrfToken: req.csrfToken() });
// For this example, we'll send a static HTML and fetch the token client-side for simplicity.
res.send(`
<!DOCTYPE html>
<html>
<head><title>CSRF Demo</title></head>
<body>
<h1>Submit Data (with CSRF protection)</h1>
<form action="/process" method="POST">
<input type="hidden" name="_csrf" value="">
<label for="name">Name:</label>
<input type="text" id="name" name="name"><br><br>
<input type="submit" value="Submit">
</form>
<script>
// Fetch CSRF token and inject into the form
fetch('/csrf-token')
.then(response => response.json())
.then(data => {
document.querySelector('input[name="_csrf"]').value = data.token;
});
</script>
</body>
</html>
`);
});
// Endpoint to provide CSRF token for client-side rendering
app.get('/csrf-token', csrfProtection, (req, res) => {
res.json({ token: req.csrfToken() });
});
// Handle POST requests with CSRF protection
app.post('/process', csrfProtection, (req, res) => {
// Access form data via req.body
console.log('Received data:', req.body);
res.send('Data processed successfully!');
});
// 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);
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log('Navigate to http://localhost:3000/ to see the form.');
});
How it works: This snippet shows how to implement CSRF (Cross-Site Request Forgery) protection using the `csurf` middleware in an Express.js application. CSRF attacks trick authenticated users into submitting unintended requests. `csurf` generates a unique, unpredictable token for each user session, which must be included in all state-changing (e.g., POST, PUT, DELETE) requests. The server validates this token, ensuring that requests originate from legitimate forms or client-side applications.