JAVASCRIPT

Implementing CSRF Protection with Express and Tokens

Secure web applications against Cross-Site Request Forgery (CSRF) attacks using `csurf` middleware in Express and managing tokens on the client-side.

// server.js (Node.js with Express)
const express = require('express');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const csurf = require('csurf');
const bodyParser = require('body-parser');

const app = express();

app.use(cookieParser());
app.use(session({
    secret: 'a_very_secret_key', // Replace with a strong, random key
    resave: false,
    saveUninitialized: true,
    cookie: {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production', // Use secure cookies in production
        sameSite: 'Lax', // or 'Strict' depending on requirements
        maxAge: 3600000 // 1 hour
    }
}));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(csurf({ cookie: true })); // Enable CSRF protection

// Route to get CSRF token
app.get('/api/csrf-token', (req, res) => {
    res.json({ csrfToken: req.csrfToken() });
});

// Protected route
app.post('/api/submit-data', (req, res) => {
    // req.csrfToken() has already been validated by csurf middleware
    // Access data from req.body
    res.send('Data submitted securely!');
});

// Error handler 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 running on http://localhost:3000');
});

// client.js (Frontend JavaScript)
async function submitSecureForm(data) {
    try {
        // Fetch CSRF token
        const tokenResponse = await fetch('/api/csrf-token');
        const tokenData = await tokenResponse.json();
        const csrfToken = tokenData.csrfToken;

        // Include CSRF token in the request headers
        const response = await fetch('/api/submit-data', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'CSRF-Token': csrfToken // Custom header for CSRF token
            },
            body: new URLSearchParams({
                'someField': data,
                '_csrf': csrfToken // Also send in body for csurf default behavior, though header is common too
            }).toString()
        });

        const result = await response.text();
        console.log(result);
    } catch (error) {
        console.error('Error submitting form:', error);
    }
}

// Example usage
// submitSecureForm('example_data_to_submit');
How it works: This snippet demonstrates implementing CSRF protection using `csurf` middleware in an Express application. The server generates a unique CSRF token for each user session, making it available via an API endpoint. Frontend JavaScript fetches this token and includes it in subsequent POST requests, either in the request body or a custom header. The `csurf` middleware automatically validates this token against the one stored in the user's session, rejecting requests with missing or invalid tokens, thus preventing CSRF attacks. The `cookie-parser`, `express-session`, and `body-parser` middlewares are prerequisites.

Need help integrating this into your project?

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

Hire DigitalCodeLabs