JAVASCRIPT

Implement CSRF Protection with Tokens in Node.js Express

Protect your Node.js Express application from Cross-Site Request Forgery (CSRF) attacks by generating and verifying CSRF tokens for state-changing requests.

const express = require('express');
const cookieParser = require('cookie-parser'); // npm install cookie-parser
const session = require('express-session');     // npm install express-session
const csurf = require('csurf');                 // npm install csurf
const bodyParser = require('body-parser');

const app = express();

// Use cookie-parser to parse cookies
app.use(cookieParser());

// Configure session middleware (required by csurf)
// In a production environment, use a more robust session store like connect-mongo or connect-redis
app.use(session({
  secret: 'your_strong_secret_key_here', // Use a strong, unique secret
  resave: false,
  saveUninitialized: true,
  cookie: {
    secure: process.env.NODE_ENV === 'production', // Set to true in production with HTTPS
    httpOnly: true, // Prevent client-side JavaScript from accessing the cookie
    sameSite: 'lax', // Protects against some CSRF and XSS attacks
    maxAge: 1000 * 60 * 60 * 24 // 24 hours
  }
}));

// Body parser for POST requests (csurf requires this before csurf middleware)
app.use(bodyParser.urlencoded({ extended: false })); // for application/x-www-form-urlencoded
app.use(bodyParser.json()); // for application/json

// CSRF protection middleware
const csrfProtection = csurf({ cookie: true });
// You can also use { session: true } and store tokens in session if you don't want client-side cookie access

// Example route to get the CSRF token (for rendering forms)
app.get('/', csrfProtection, (req, res) => {
  // Pass the CSRF token to your frontend template
  res.send(`
        <html>
          <body>
            <h1>Submit a Post</h1>
            <form action="/process" method="POST">
              <input type="text" name="title" placeholder="Title">
              <input type="hidden" name="_csrf" value="${req.csrfToken()}">
              <button type="submit">Submit</button>
            </form>
            <p>Your CSRF Token: <strong>${req.csrfToken()}</strong></p>
          </body>
        </html>
      `);
});

// Example route to process a form submission
app.post('/process', csrfProtection, (req, res) => {
  // If the token is valid, req.body._csrf will match the cookie/session token
  // and the request will proceed. Otherwise, csurf will throw an error.
  console.log('Processed data:', req.body.title);
  res.send('Form submitted successfully!');
});

// Error handling for CSRF issues
app.use((err, req, res, next) => {
  if (err.code !== 'EBADCSRFTOKEN') return next(err);

  res.status(403);
  res.send('Invalid CSRF token. Request blocked.');
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});
How it works: This Node.js Express snippet demonstrates how to implement Cross-Site Request Forgery (CSRF) protection using the `csurf` middleware. It generates a unique, secret token for each user session. For state-changing requests (like POST, PUT, DELETE), this token must be included in the request body (e.g., as a hidden form field) and is compared against the token stored in the server's session or a cookie. If they don't match, the request is rejected, preventing attackers from forging requests on behalf of authenticated users.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs