What is csurf?
The csurf npm package is a middleware for Node.js that provides Cross-Site Request Forgery (CSRF) protection. It helps secure web applications by ensuring that state-changing requests are made by authenticated users and not by malicious actors.
What are csurf's main functionalities?
Basic CSRF Protection
This code demonstrates how to set up basic CSRF protection using the csurf middleware in an Express application. It includes setting up the middleware, generating a CSRF token, and embedding it in a form.
const express = require('express');
const csrf = require('csurf');
const cookieParser = require('cookie-parser');
const app = express();
const csrfProtection = csrf({ cookie: true });
app.use(cookieParser());
app.use(csrfProtection);
app.get('/form', (req, res) => {
res.send(`<form action="/process" method="POST">
<input type="hidden" name="_csrf" value="${req.csrfToken()}">
<button type="submit">Submit</button>
</form>`);
});
app.post('/process', (req, res) => {
res.send('Form processed');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
CSRF Protection with Session Storage
This example shows how to use csurf with session storage for CSRF protection. The session middleware is used to store the CSRF token, which is then embedded in a form and validated upon form submission.
const express = require('express');
const session = require('express-session');
const csrf = require('csurf');
const app = express();
const csrfProtection = csrf();
app.use(session({ secret: 'mySecret', resave: false, saveUninitialized: true }));
app.use(csrfProtection);
app.get('/form', (req, res) => {
res.send(`<form action="/process" method="POST">
<input type="hidden" name="_csrf" value="${req.csrfToken()}">
<button type="submit">Submit</button>
</form>`);
});
app.post('/process', (req, res) => {
res.send('Form processed');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Other packages similar to csurf
helmet
Helmet is a collection of middleware functions that help secure Express applications by setting various HTTP headers. While it does not provide CSRF protection directly, it offers a range of other security features such as XSS protection, content security policy, and more. It can be used alongside csurf for comprehensive security.
lusca
Lusca is another security middleware for Express that provides various security features, including CSRF protection. It is similar to csurf but also includes additional features like XSS protection, HSTS, and CORS. Lusca can be a more comprehensive solution if you need multiple security features in one package.
csurf
![Test coverage](https://img.shields.io/coveralls/expressjs/csurf.svg?style=flat)
Node.js CSRF protection middleware.
Requires either a session middleware or cookie-parser to be initialized first.
Install
$ npm install csurf
API
var csrf = require('csurf')
csrf(options)
This middleware adds a req.csrfToken()
function to make a token which should be added to requests which mutate state, within a hidden form field, query-string etc. This token is validated against the visitor's session or csrf cookie.
Options
value
a function accepting the request, returning the token.
- The default function checks four possible token locations:
_csrf
parameter in req.body
generated by the body-parser
middleware._csrf
parameter in req.query
generated by query()
.x-csrf-token
and x-xsrf-token
header fields.
cookie
set to a truthy value to enable cookie-based instead of session-based csrf secret storage.
- If
cookie
is an object, these options can be configured, otherwise defaults are used:
key
the name of the cookie to use (defaults to _csrf
) to store the csrf secret- any other res.cookie options can be set
ignoreMethods
An array of the methods CSRF token checking will disabled.
(default: ['GET', 'HEAD', 'OPTIONS']
)
req.csrfToken()
Lazy-loads the token associated with the request.
Example
Simple express example
The following is an example of some server-side code that protects all
non-GET/HEAD/OPTIONS routes with a CSRF token.
var express = require('express')
var csrf = require('csurf')
var app = express()
app.use(csrf())
app.use(function (err, req, res, next) {
if (err.code !== 'EBADCSRFTOKEN') return next(err)
res.status(403)
res.send('session has expired or form tampered with')
})
app.get('/form', function(req, res) {
res.render('send', { csrfToken: req.csrfToken() })
})
Inside the view (depending on your template language; handlebars-style
is demonstrated here), set the csrfToken
value as the value of a hidden
input field named _csrf
:
<form action="/process" method="POST">
<input type="hidden" name="_csrf" value="{{csrfToken}}">
Favorite color: <input type="text" name="favoriteColor">
<button type="submit">Submit</button>
</form>
Custom error handling
var express = require('express')
var csrf = require('csurf')
var app = express()
app.use(csrf())
app.use(function (err, req, res, next) {
if (err.code !== 'EBADCSRFTOKEN') return next(err)
res.status(403)
res.send('session has expired or form tampered with')
})
License
MIT