als-csrf
v1.4.0
Published
A lightweight CSRF protection middleware for Node.js applications, providing token-based security for state-changing requests.
Downloads
185
Maintainers
Readme
als-csrf
als-csrf
is a middleware for Node.js applications to protect against Cross-Site Request Forgery (CSRF) attacks. It integrates seamlessly with HTTP server frameworks such as Express to provide CSRF token validation and generation based on cookie.
Chage log
- V1.4
- dependencies updated
- prefix and crypt options
- V1.3
- Fixed maxAge for csrf token
- V1.2
- generating new token if not valid on get method
- if csrf token expired, message includes "refresh the page"
- updated als-cookie
Installation
Install als-csrf
using npm:
npm install als-csrf
Quick Start
To integrate als-csrf
with an Express application, simply apply the middleware to your routes. CSRF tokens will be automatically generated for all GET requests and validated for subsequent state-changing requests specified in the methods
parameter.
Here's a quick example to get you started with als-csrf
in an Express application:
const express = require('express');
const csrf = require('als-csrf');
const app = express();
app.use(csrf());
or with http:
const csrf = require('als-csrf')
http.createServer(csrf()(req,res,(req,res) => {
}))
This setup will protect all POST, PUT, PATCH, and DELETE routes by verifying the presence of a valid CSRF token in the cookies sent with each request.
In cases above csrf middleware will be activated with default parameters. The default parameters:
const defaultParameters = {
// set the cookie as SameSite. default is lax
sameSite:'lax',
// file path for saving start token. default ./lib/csrf-start
filePath:'csrf-start',
// maxAge for csrf
maxAge: 60 * 60 * 24,
// error handler
logger: console.log,
// methods for csrf validation
methods:['PUT','POST','PATCH','DELETE'],
// http error handler for declined csrf validations
httpErrorHandler: (res, status, message) => {
res.writeHead(status);
res.end(message);
},
prefix:'s:', // optional
cryptOptions:{}, // optional
}
Advanced usage
The advanced usage, requires custom parameters:
const express = require('express');
const csrf = require('als-csrf');
const Logger = require('als-logger');
const app = express();
const { httpErrorHandler } = require('als-http-error');
const maxAge = 3600000
const logger = new Logger('/path/to/logs', {});
const methods = ['POST', 'PUT', 'DELETE'] // Methods to protect
const csrfProtection = csrf({maxAge,logger,httpErrorHandler,methods});
app.use(csrfProtection)
app.get('/', (req, res) => {
res.end('CSRF token is set!')
});
app.post('/submit', (req, res) => {
res.end('Data received with valid CSRF token!');
});
app.listen(3000, () => console.log('Server running on http://localhost:3000'));
API
csrf(options)
Creates a CSRF protection middleware with the following options:
sameSite
: set the cookie as SameSite. default is laxfilePath
: file path for saving start token. default ./lib/csrf-startmaxAge
: The duration in milliseconds for which the token is valid.logger
: Function to log errors or information.httpErrorHandler
: Custom function to handle HTTP errors when CSRF validation fails.- Has to be with res, status, message parameters
methods
: Array of HTTP methods to protect against CSRF attacks. Supported methods include 'GET', 'POST', 'PUT', 'DELETE', etc.prefix
(String, optional) - prefix for encryptioncryptOptions
(Object, optional) - options for encryption- more information : als-crypt
Token Management
Tokens are generated on GET requests and expected to be sent back on subsequent state-changing requests (POST, PUT, DELETE, etc.). The middleware checks for the presence and validity of the token in cookies.
Examples
Checking for Expired Tokens
In your tests or in development, you may want to simulate token expiration:
// Simulating an expired token scenario
const csrfProtection = csrf({
maxAge: 50, // Very short expiry time
logger: console.error,
httpErrorHandler: (res, status, message) => {
res.status(status).send({ error: message });
}
});
app.post('/test-expired', csrfProtection, (req, res) => {
res.send('This should not work with an expired token!');
});
How it Works
Token Generation and Validation
als-csrf
operates by generating and validating tokens based on the elapsed time since an initial starting point:
- Token Generation: A CSRF token is only generated for GET requests. This token is then expected to be included in subsequent requests that perform state changes (POST, PUT, DELETE, etc.).
- Token Validation: The middleware checks for the presence of the token in cookies for requests that are specified in the
methods
option (e.g., POST, PUT). The validation of the token includes checking if the token has expired and if the token corresponds to the time elapsed since the initial start.
Security Details
Each token represents the elapsed time from the initial start, which is recorded and stored in a file at the first initialization. This start time is critical for validating tokens as it serves as a reference point.
Token Rejection Conditions
A token is considered invalid and hence rejected in the following scenarios:
- Expired Token: If the elapsed time encoded in the token is greater than the
maxAge
, the token is considered expired. - Future Time Token: If the token represents a time that is beyond the current time, it indicates a discrepancy and leads to rejection.
Encryption
Every token is encrypted with a secret key that is automatically generated during the first initialization. For a token to be considered valid, the server must be able to decrypt it using this secret key, ensuring that only tokens generated by the server are accepted.
Security Best Practices
To ensure the security of the CSRF protection mechanism, it is crucial to handle the initial start time and the secret key securely. These should not be accessible or modifiable from outside the server environment, and care should be taken to prevent unauthorized access to the filesystem where the start time is stored.
License
als-csrf
is MIT licensed.