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.

Need help integrating this into your project?

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

Hire DigitalCodeLabs