Socket
Socket
Sign inDemoInstall

csurf

Package Overview
Dependencies
Maintainers
6
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 1.8.3 to 1.9.0

31

HISTORY.md

@@ -0,1 +1,32 @@

1.9.0 / 2016-05-27
==================
* Pass invalid csrf token error to `next()` instead of throwing
* Pass misconfigured error to `next()` instead of throwing
* Provide misconfigured error when using cookies without cookie-parser
* deps: cookie@0.3.1
- Add `sameSite` option
- Fix cookie `Max-Age` to never be a floating point number
- Improve error message when `expires` is not a `Date`
- Throw better error for invalid argument to parse
- Throw on invalid values provided to `serialize`
- perf: enable strict mode
- perf: hoist regular expression
- perf: use for loop in parse
- perf: use string concatination for serialization
* deps: csrf@~3.0.3
- Use `tsscmp` module for timing-safe token verification
- deps: base64-url@1.2.2
- deps: rndm@1.2.0
- deps: uid-safe@2.1.1
* deps: http-errors@~1.5.0
- Add `HttpError` export, for `err instanceof createError.HttpError`
- Support new code `421 Misdirected Request`
- Use `setprototypeof` module to replace `__proto__` setting
- deps: inherits@2.0.1
- deps: statuses@'>= 1.3.0 < 2'
- perf: enable strict mode
* perf: enable strict mode
* perf: remove argument reassignment
1.8.3 / 2015-06-10

@@ -2,0 +33,0 @@ ==================

159

index.js

@@ -5,6 +5,8 @@ /*!

* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* Copyright(c) 2014-2016 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**

@@ -15,8 +17,15 @@ * Module dependencies.

var Cookie = require('cookie');
var createError = require('http-errors');
var sign = require('cookie-signature').sign;
var Tokens = require('csrf');
var Cookie = require('cookie')
var createError = require('http-errors')
var sign = require('cookie-signature').sign
var Tokens = require('csrf')
/**
* Module exports.
* @public
*/
module.exports = csurf
/**
* CSRF protection middleware.

@@ -31,24 +40,24 @@ *

* @return {Function} middleware
* @api public
* @public
*/
module.exports = function csurf(options) {
options = options || {};
function csurf (options) {
var opts = options || {}
// get cookie options
var cookie = getCookieOptions(options.cookie)
var cookie = getCookieOptions(opts.cookie)
// get session options
var sessionKey = options.sessionKey || 'session'
var sessionKey = opts.sessionKey || 'session'
// get value getter
var value = options.value || defaultValue
var value = opts.value || defaultValue
// token repo
var tokens = new Tokens(options);
var tokens = new Tokens(opts)
// ignored methods
var ignoreMethods = options.ignoreMethods === undefined
var ignoreMethods = opts.ignoreMethods === undefined
? ['GET', 'HEAD', 'OPTIONS']
: options.ignoreMethods
: opts.ignoreMethods

@@ -62,10 +71,16 @@ if (!Array.isArray(ignoreMethods)) {

return function csrf(req, res, next) {
var secret = getsecret(req, sessionKey, cookie)
return function csrf (req, res, next) {
// validate the configuration against request
if (!verifyConfiguration(req, sessionKey, cookie)) {
return next(new Error('misconfigured csrf'))
}
// get the secret from the request
var secret = getSecret(req, sessionKey, cookie)
var token
// lazy-load token getter
req.csrfToken = function csrfToken() {
req.csrfToken = function csrfToken () {
var sec = !cookie
? getsecret(req, sessionKey, cookie)
? getSecret(req, sessionKey, cookie)
: secret

@@ -81,3 +96,3 @@

sec = tokens.secretSync()
setsecret(req, res, sessionKey, sec, cookie)
setSecret(req, res, sessionKey, sec, cookie)
}

@@ -97,8 +112,10 @@

secret = tokens.secretSync()
setsecret(req, res, sessionKey, secret, cookie)
setSecret(req, res, sessionKey, secret, cookie)
}
// verify the incoming token
if (!ignoreMethod[req.method]) {
verifytoken(req, tokens, secret, value(req))
if (!ignoreMethod[req.method] && !tokens.verify(secret, value(req))) {
return next(createError(403, 'invalid csrf token', {
code: 'EBADCSRFTOKEN'
}))
}

@@ -108,3 +125,3 @@

}
};
}

@@ -120,9 +137,9 @@ /**

function defaultValue(req) {
return (req.body && req.body._csrf)
|| (req.query && req.query._csrf)
|| (req.headers['csrf-token'])
|| (req.headers['xsrf-token'])
|| (req.headers['x-csrf-token'])
|| (req.headers['x-xsrf-token']);
function defaultValue (req) {
return (req.body && req.body._csrf) ||
(req.query && req.query._csrf) ||
(req.headers['csrf-token']) ||
(req.headers['xsrf-token']) ||
(req.headers['x-csrf-token']) ||
(req.headers['x-xsrf-token'])
}

@@ -138,3 +155,3 @@

function getCookieOptions(options) {
function getCookieOptions (options) {
if (options !== true && typeof options !== 'object') {

@@ -170,3 +187,3 @@ return undefined

function getIgnoredMethods(methods) {
function getIgnoredMethods (methods) {
var obj = Object.create(null)

@@ -191,20 +208,37 @@

function getsecret(req, sessionKey, cookie) {
var secret
function getSecret (req, sessionKey, cookie) {
// get the bag & key
var bag = getSecretBag(req, sessionKey, cookie)
var key = cookie ? cookie.key : 'csrfSecret'
if (!bag) {
/* istanbul ignore next: should never actually run */
throw new Error('misconfigured csrf')
}
// return secret from bag
return bag[key]
}
/**
* Get the token secret bag from the request.
*
* @param {IncomingMessage} req
* @param {String} sessionKey
* @param {Object} [cookie]
* @api private
*/
function getSecretBag (req, sessionKey, cookie) {
if (cookie) {
// get secret from cookie
var bag = cookie.signed
var cookieKey = cookie.signed
? 'signedCookies'
: 'cookies'
secret = req[bag][cookie.key]
} else if (req[sessionKey]) {
return req[cookieKey]
} else {
// get secret from session
secret = req[sessionKey].csrfSecret
} else {
throw new Error('misconfigured csrf')
return req[sessionKey]
}
return secret
}

@@ -222,11 +256,11 @@

function setcookie(res, name, val, options) {
var data = Cookie.serialize(name, val, options);
function setCookie (res, name, val, options) {
var data = Cookie.serialize(name, val, options)
var prev = res.getHeader('set-cookie') || [];
var prev = res.getHeader('set-cookie') || []
var header = Array.isArray(prev) ? prev.concat(data)
: Array.isArray(data) ? [prev].concat(data)
: [prev, data];
: [prev, data]
res.setHeader('set-cookie', header);
res.setHeader('set-cookie', header)
}

@@ -245,3 +279,3 @@

function setsecret(req, res, sessionKey, val, cookie) {
function setSecret (req, res, sessionKey, val, cookie) {
if (cookie) {

@@ -253,3 +287,4 @@ // set secret on cookie

if (!secret) {
throw new Error('cookieParser("secret") required for signed cookies')
/* istanbul ignore next: should never actually run */
throw new Error('misconfigured csrf')
}

@@ -260,3 +295,3 @@

setcookie(res, cookie.key, val, cookie);
setCookie(res, cookie.key, val, cookie)
} else if (req[sessionKey]) {

@@ -272,18 +307,16 @@ // set secret on session

/**
* Verify the token.
*
* @param {IncomingMessage} req
* @param {Object} tokens
* @param {string} secret
* @param {string} val
* @api private
* Verify the configuration against the request.
* @private
*/
function verifytoken(req, tokens, secret, val) {
// valid token
if (!tokens.verify(secret, val)) {
throw createError(403, 'invalid csrf token', {
code: 'EBADCSRFTOKEN'
});
function verifyConfiguration (req, sessionKey, cookie) {
if (!getSecretBag(req, sessionKey, cookie)) {
return false
}
if (cookie && cookie.signed && !req.secret) {
return false
}
return true
}
{
"name": "csurf",
"description": "CSRF token middleware",
"version": "1.8.3",
"version": "1.9.0",
"author": "Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)",

@@ -12,15 +12,19 @@ "contributors": [

"dependencies": {
"cookie": "0.1.3",
"cookie": "0.3.1",
"cookie-signature": "1.0.6",
"csrf": "~3.0.0",
"http-errors": "~1.3.1"
"csrf": "~3.0.3",
"http-errors": "~1.5.0"
},
"devDependencies": {
"body-parser": "~1.12.4",
"connect": "3",
"cookie-parser": "~1.3.5",
"body-parser": "1.15.1",
"connect": "3.4.1",
"cookie-parser": "1.4.3",
"cookie-session": "~1.1.0",
"istanbul": "0.3.15",
"mocha": "2.2.5",
"supertest": "1.0.1"
"eslint": "2.10.2",
"eslint-config-standard": "5.3.1",
"eslint-plugin-promise": "1.3.1",
"eslint-plugin-standard": "1.3.2",
"istanbul": "0.4.3",
"mocha": "2.5.3",
"supertest": "1.1.0"
},

@@ -31,2 +35,3 @@ "engines": {

"scripts": {
"lint": "eslint **/*.js",
"test": "mocha --check-leaks --reporter spec --bail test/",

@@ -33,0 +38,0 @@ "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot test/",

@@ -147,2 +147,53 @@ # csurf

### Ignoring Routes
**Note** CSRF checks should only be disabled for requests that you expect to
come from outside of your website. Do not disable CSRF checks for requests
that you expect to only come from your website. An existing session, even if
it belongs to an authenticated user, is not enough to protect against CSRF
attacks.
The following is an example of how to order your routes so that certain endpoints
do not check for a valid CSRF token.
```js
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// create express app
var app = express()
// create api router
var api = createApiRouter()
// mount api before csrf is appended to the app stack
app.use('/api', api)
// now add csrf and other middlewares, after the "/api" was mounted
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(csrf({ cookie: true }))
app.get('/form', function(req, res) {
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', function(req, res) {
res.send('csrf was required to get here')
})
function createApiRouter() {
var router = new express.Router()
router.post('/getProfile', function(req, res) {
res.send('no csrf to get here')
})
return router
}
```
### Custom error handling

@@ -149,0 +200,0 @@

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