Socket
Socket
Sign inDemoInstall

csurf

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

csurf - npm Package Compare versions

Comparing version 0.1.2 to 1.0.0

.travis.yml

197

index.js

@@ -1,85 +0,158 @@

var crypto = require('crypto')
var uid = require('uid')
/*!
* Connect - csrf
* Copyright(c) 2011 Sencha Inc.
* MIT Licensed
*/
var ignoreMethods = {
GET: true,
HEAD: true,
OPTIONS: true
}
/**
* Module dependencies.
*/
exports.get = function () {
var csrf = this._csrf
if (csrf)
return csrf
var uid = require('uid2');
var crypto = require('crypto');
var salt = uid()
/**
* Anti CSRF:
*
* CSRF protection middleware.
*
* 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.
*
* The default `value` function checks `req.body` generated
* by the `bodyParser()` middleware, `req.query` generated
* by `query()`, and the "X-CSRF-Token" header field.
*
* This middleware requires session support, thus should be added
* somewhere _below_ `session()` and `cookieParser()`.
*
* Options:
*
* - `value` a function accepting the request, returning the token
*
* @param {Object} options
* @api public
*/
return this._csrf = salt + ';'
+ createHash(salt, this.session.secret)
}
module.exports = function csrf(options) {
options = options || {};
var value = options.value || defaultValue;
exports.set = function (req, res, next) {
var secret = req.session.secret
if (secret)
return next()
return function(req, res, next){
crypto.pseudoRandomBytes(24, function (err, buf) {
if (err)
return next(err)
// already have one
var secret = req.session.csrfSecret;
if (secret) return createToken(secret);
req.session.secret = buf.toString('base64')
next()
})
}
// generate secret
uid(24, function(err, secret){
if (err) return next(err);
req.session.csrfSecret = secret;
createToken(secret);
});
exports.check = function (req, res, next) {
if (ignoreMethods[req.method])
return next()
// generate the token
function createToken(secret) {
var token;
check(req, res, next, req.headers['x-csrf-token']
|| (req.body && req.body._csrf)
)
}
// lazy-load token
req.csrfToken = function csrfToken() {
return token || (token = saltedToken(secret));
};
exports.checkBody = function (req, res, next) {
if (ignoreMethods[req.method])
return next()
// ignore these methods
if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next();
check(req, res, next, req.body && req.body._csrf)
// determine user-submitted value
var val = value(req);
// check
if (!checkToken(val, secret)) {
var err = new Error('invalid csrf token');
err.status = 403;
next(err);
return;
}
next();
}
}
};
/**
* Default value function, checking the `req.body`
* and `req.query` for the CSRF token.
*
* @param {IncomingMessage} req
* @return {String}
* @api private
*/
function defaultValue(req) {
return (req.body && req.body._csrf)
|| (req.query && req.query._csrf)
|| (req.headers['x-csrf-token'])
|| (req.headers['x-xsrf-token']);
}
exports.checkHeader = function (req, res, next) {
if (ignoreMethods[req.method])
return next()
/**
* Return salted token.
*
* @param {String} secret
* @return {String}
* @api private
*/
check(req, res, next, req.headers['x-csrf-token'])
function saltedToken(secret) {
return createToken(generateSalt(10), secret);
}
function check(req, res, next, value) {
if (!value)
return next(passError(403))
/**
* Creates a CSRF token from a given salt and secret.
*
* @param {String} salt (should be 10 characters)
* @param {String} secret
* @return {String}
* @api private
*/
var secret = req.session.secret
if (!secret)
return next(passError(403))
function createToken(salt, secret) {
return salt + crypto
.createHash('sha1')
.update(salt + secret)
.digest('base64');
}
var frags = value.split(';')
var salt = frags[0]
var hash = frags[1]
if (!hash || createHash(salt, secret) !== hash)
return next(passError(403))
/**
* Checks if a given CSRF token matches the given secret.
*
* @param {String} token
* @param {String} secret
* @return {Boolean}
* @api private
*/
next()
function checkToken(token, secret) {
if ('string' != typeof token) return false;
return token === createToken(token.slice(0, 10), secret);
}
function createHash(salt, secret) {
return crypto.createHash('sha1')
.update(salt + ';' + secret)
.digest('base64')
/**
* Generates a random salt, using a fast non-blocking PRNG (Math.random()).
*
* @param {Number} length
* @return {String}
* @api private
*/
function generateSalt(length) {
var i, r = [];
for (i = 0; i < length; ++i) {
r.push(SALTCHARS[Math.floor(Math.random() * SALTCHARS.length)]);
}
return r.join('');
}
function passError(status) {
var err = new Error()
err.status = status
return err
}
var SALTCHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
{
"name": "csurf",
"description": "CSRF middleware",
"version": "0.1.2",
"description": "CSRF token middleware",
"version": "1.0.0",
"author": {

@@ -11,14 +11,25 @@ "name": "Jonathan Ong",

},
"dependencies": {
"uid": "~0.0.2"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/discore/csurf.git"
"url": "https://github.com/expressjs/csurf.git"
},
"bugs": {
"mail": "me@jongleberry.com",
"url": "https://github.com/discore/csurf/issues"
"url": "https://github.com/expressjs/csurf/issues"
},
"dependencies": {
"uid2": "~0.0.2"
},
"devDependencies": {
"cookie-session": "*",
"body-parser": "*",
"mocha": "^1.17.0",
"should": "^3.0.0",
"supertest": "*",
"connect": "*"
},
"scripts": {
"test": "make test"
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc