Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

crumb

Package Overview
Dependencies
Maintainers
2
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

crumb - npm Package Compare versions

Comparing version 3.3.0 to 4.0.0

28

example/restful.js
var Hapi = require('hapi');
var server = Hapi.createServer('127.0.0.1', 8000);
var server = new Hapi.Server();
server.connection({ host: '127.0.0.1', port: 8000 });
// Add Crumb plugin
server.pack.register({ plugin: require('../'), options: { restful: true } }, function(err) {
if (err) throw err;
server.register({ register: require('../'), options: { restful: true } }, function (err) {
if (err) {
throw err;
}
});

@@ -18,5 +22,6 @@

path: '/generate',
handler: function(request) {
handler: function (request, reply) {
// return crumb if desired
request.reply('{ "crumb": ' + request.plugins.crumb + ' }');
return reply('{ "crumb": ' + request.plugins.crumb + ' }');
}

@@ -30,11 +35,12 @@ },

path: '/crumbed',
handler: function(request) {
request.reply('Crumb route');
handler: function (request, reply) {
return reply('Crumb route');
}
},
}
]);
server.start(function() {
server.start(function () {
console.log('Example restful server running at:', server.info.uri);
});
});
var Hapi = require('hapi');
var serverOptions = {
views: {
path: __dirname + '/templates',
engines: {
html: require('handlebars')
}
var server = new Hapi.Server();
server.connection({ host: '127.0.0.1', port: 8000 });
server.views({
path: __dirname + '/templates',
engines: {
html: require('handlebars')
}
};
});
var server = new Hapi.Server('127.0.0.1', 8000, serverOptions);
server.register({ register: require('../'), options: { cookieOptions: { isSecure: false } } }, function (err) {
server.pack.register({ plugin: require('../'), options: { cookieOptions: { isSecure: false } } }, function (err) {
if (err) throw err;
if (err) {
throw err;
}
});

@@ -22,2 +24,3 @@

handler: function (request, reply) {
return reply.view('index', { title: 'test', message: 'hi' });

@@ -31,2 +34,3 @@ }

handler: function (request, reply) {
return reply.view('message', { title: 'test', message: request.payload.message });

@@ -37,3 +41,4 @@ }

server.start(function () {
console.log('Example server running at:', server.info.uri);
});

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

module.exports = require('./lib');
module.exports = require('./lib');
// Load modules
var Hoek = require('hoek');
var Stream = require('stream');
var Boom = require('boom');
var Cryptiles = require('cryptiles');
var Hoek = require('hoek');
var Joi = require('joi');
var schema = require('./schema');

@@ -14,2 +14,15 @@

internals.schema = Joi.object().keys({
key: Joi.string().optional(),
size: Joi.number().optional(),
autoGenerate: Joi.boolean().optional(),
addToViewContext: Joi.boolean().optional(),
cookieOptions: Joi.object().keys(null),
restful: Joi.boolean().optional(),
skip: Joi.any().optional(),
allowOrigins: Joi.array().excludes(Joi.string().valid('*')).optional()
});
internals.defaults = {

@@ -25,13 +38,137 @@ key: 'crumb',

skip: false, // Set to a function which returns true when to skip crumb generation and validation
allowOrigins: null // A list of CORS origins to set crumb cookie on. Defaults to server.settings.cors.origin
allowOrigins: null // A list of CORS origins to set crumb cookie on. Defaults to request.route.settings.settings.cors.origin
};
// Not used in restful mode
internals.routeDefaults = {
key: 'crumb', // query or payload key
source: 'payload', // Crumb key source: 'payload', 'query'
restful: false
exports.register = function (server, options, next) {
Joi.assert(options, internals.schema, 'Invalid crumb options');
var settings = Hoek.applyToDefaults(internals.defaults, options);
var routeDefaults = {
key: settings.key,
restful: settings.resful,
source: 'payload'
};
server.state(settings.key, settings.cookieOptions);
server.ext('onPostAuth', function (request, reply) {
// If skip function enabled. Call it and if returns true, do not attempt to do anything with crumb.
if (settings.skip && typeof settings.skip === 'function' && settings.skip(request, reply)) {
return reply.continue();
}
// Validate incoming crumb
if (typeof request.route.settings.plugins._crumb === 'undefined') {
if (request.route.settings.plugins.crumb ||
!request.route.settings.plugins.hasOwnProperty('crumb') && settings.autoGenerate) {
request.route.settings.plugins._crumb = Hoek.applyToDefaults(routeDefaults, request.route.settings.plugins.crumb || {});
}
else {
request.route.settings.plugins._crumb = false;
}
}
// Set crumb cookie and calculate crumb
if ((settings.autoGenerate ||
request.route.settings.plugins._crumb) &&
(request.route.settings.cors ? internals.originParser(request.headers.origin, settings.allowOrigins || request.route.settings.cors.origin, request) : true)) {
generate(request, reply);
}
// Validate crumb
if (settings.restful === false ||
(!request.route.settings.plugins._crumb || request.route.settings.plugins._crumb.restful === false)) {
if (request.method !== 'post' ||
!request.route.settings.plugins._crumb) {
return reply.continue();
}
var content = request[request.route.settings.plugins._crumb.source];
if (content instanceof Stream) {
return reply(Boom.forbidden());
}
if (content[request.route.settings.plugins._crumb.key] !== request.plugins.crumb) {
return reply(Boom.forbidden());
}
// Remove crumb
delete request[request.route.settings.plugins._crumb.source][request.route.settings.plugins._crumb.key];
}
else {
if (request.method !== 'post' && request.method !== 'put' && request.method !== 'patch' && request.method !== 'delete' ||
!request.route.settings.plugins._crumb) {
return reply.continue();
}
var header = request.headers['x-csrf-token'];
if (!header) {
return reply(Boom.forbidden());
}
if (header !== request.plugins.crumb) {
return reply(Boom.forbidden());
}
}
return reply.continue();
});
server.ext('onPreResponse', function (request, reply) {
// Add to view context
var response = request.response;
if (settings.addToViewContext &&
request.plugins.crumb &&
request.route.settings.plugins._crumb &&
!response.isBoom &&
response.variety === 'view') {
response.source.context = response.source.context || {};
response.source.context[request.route.settings.plugins._crumb.key] = request.plugins.crumb;
}
return reply.continue();
});
var generate = function (request, reply) {
var crumb = request.state[settings.key];
if (!crumb) {
crumb = Cryptiles.randomString(settings.size);
reply.state(settings.key, crumb, settings.cookieOptions);
}
request.plugins.crumb = crumb;
return request.plugins.crumb;
};
server.expose({ generate: generate });
return next();
};
exports.register.attributes = {
pkg: require('../package.json')
};
// Strip http or https from request host

@@ -54,4 +191,5 @@

return this._host;
}
};
// Parses allowOrigin setting

@@ -61,3 +199,3 @@

var host = internals.trimHost(request.server.info.uri);
var host = internals.trimHost(request.connection.info.uri);
var requestHost = internals.trimHost(request.headers.host);

@@ -87,3 +225,3 @@ this._match = false;

for (var i = 0, allowOriginsLen = allowOrigins.length; i < allowOriginsLen; i++) {
for (var i = 0, il = allowOrigins.length; i < il; ++i) {
if (allowOrigins[i] === '*') {

@@ -101,4 +239,4 @@ return false;

else {
for (var ii = 0, allowOriginPartsLen = this._originAllowParts.length; ii < allowOriginPartsLen; ii++) {
this._match = this._originAllowParts[ii] === '*' || this._originAllowParts[ii] === this._originParts[ii];
for (var j = 0, jl = this._originAllowParts.length; j < jl; ++j) {
this._match = this._originAllowParts[j] === '*' || this._originAllowParts[j] === this._originParts[j];
if (!this._match) {

@@ -113,142 +251,4 @@ break;

}
return this._match;
}
exports.register = function (plugin, options, next) {
// Start with options validation
Joi.validate(options, schema, { convert: false }, function (err, value) {
if (err) {
//plugin.hapi.error.internal('Invalid plugin options for crumb', err);
return next('Invalid plugin options for crumb: ' + JSON.stringify(err));
}
var settings = Hoek.applyToDefaults(internals.defaults, options);
// copy the key and restful settings from internals.defaults to internals.routeDefaults for consistency
internals.routeDefaults.key = settings.key;
internals.routeDefaults.restful = settings.restful;
plugin.state(settings.key, settings.cookieOptions);
plugin.ext('onPostAuth', function (request, reply) {
// If skip function enabled. Call it and if returns true, do not attempt to do anything with crumb.
if (settings.skip && typeof settings.skip === 'function' && settings.skip(request, reply)) {
return reply();
}
// Validate incoming crumb
if (typeof request.route.plugins._crumb === 'undefined') {
if (request.route.plugins.crumb ||
!request.route.plugins.hasOwnProperty('crumb') && settings.autoGenerate) {
request.route.plugins._crumb = Hoek.applyToDefaults(internals.routeDefaults, request.route.plugins.crumb || {});
}
else {
request.route.plugins._crumb = false;
}
}
// Set crumb cookie and calculate crumb
if ((settings.autoGenerate ||
request.route.plugins._crumb) &&
(request.server.settings.cors ? internals.originParser(request.headers.origin, settings.allowOrigins || request.server.settings.cors.origin, request) : true)) {
generate(request, reply);
}
// Validate crumb
if (settings.restful === false ||
(!request.route.plugins._crumb || request.route.plugins._crumb.restful === false)) {
if (request.method !== 'post' ||
!request.route.plugins._crumb) {
return reply();
}
var content = request[request.route.plugins._crumb.source];
if (content instanceof Stream) {
return reply(plugin.hapi.error.forbidden());
}
if (content[request.route.plugins._crumb.key] !== request.plugins.crumb) {
return reply(plugin.hapi.error.forbidden());
}
// Remove crumb
delete request[request.route.plugins._crumb.source][request.route.plugins._crumb.key];
}
else {
if (request.method !== 'post' && request.method !== 'put' && request.method !== 'patch' && request.method !== 'delete' ||
!request.route.plugins._crumb) {
return reply();
}
var header = request.headers['x-csrf-token'];
if (!header) {
return reply(plugin.hapi.error.forbidden());
}
if (header !== request.plugins.crumb) {
return reply(plugin.hapi.error.forbidden());
}
}
return reply();
});
plugin.ext('onPreResponse', function (request, reply) {
// Add to view context
var response = request.response;
if (settings.addToViewContext &&
request.plugins.crumb &&
request.route.plugins._crumb &&
!response.isBoom &&
response.variety === 'view') {
response.source.context = response.source.context || {};
response.source.context[request.route.plugins._crumb.key] = request.plugins.crumb;
}
return reply();
});
var generate = function (request, reply) {
var crumb = request.state[settings.key];
if (!crumb) {
crumb = Cryptiles.randomString(settings.size);
reply.state(settings.key, crumb, settings.cookieOptions);
}
request.plugins.crumb = crumb;
return request.plugins.crumb;
};
plugin.expose({ generate: generate });
return next();
});
};
exports.register.attributes = {
pkg: require('../package.json')
};
{
"name": "crumb",
"description": "CSRF crumb generation and validation plugin",
"version": "3.3.0",
"author": "Eran Hammer <eran@hammer.io> (http://hueniverse.com)",
"contributors": [
"Marcus Stong <stongo@gmail.com>",
"Nathan LaFreniere <quitlahok@gmail.com>",
"Tom Steele <thomasjsteele@gmail.com>"
],
"version": "4.0.0",
"repository": "git://github.com/hapijs/crumb",

@@ -24,5 +18,6 @@ "bugs": {

"engines": {
"node": ">=0.10.30"
"node": ">=0.10.32"
},
"dependencies": {
"boom": "2.x.x",
"cryptiles": "2.x.x",

@@ -33,8 +28,9 @@ "hoek": "2.x.x",

"peerDependencies": {
"hapi": ">=2.x.x"
"hapi": ">=8.x.x"
},
"devDependencies": {
"hapi": "6.x.x",
"code": "1.x.x",
"handlebars": "1.3.x",
"lab": "3.x.x"
"hapi": "8.x.x",
"lab": "5.x.x"
},

@@ -41,0 +37,0 @@ "scripts": {

// Load modules
var Stream = require('stream');
var Code = require('code');
var Crumb = require('../');
var Hapi = require('hapi');
var Lab = require('lab');
var Hapi = require('hapi');
var Crumb = require('../');
var Stream = require('stream');
var Hoek = require('hoek');

@@ -17,7 +18,6 @@

var expect = Lab.expect;
var before = Lab.before;
var after = Lab.after;
var describe = Lab.experiment;
var it = Lab.test;
var lab = exports.lab = Lab.script();
var describe = lab.describe;
var it = lab.it;
var expect = Code.expect;

@@ -27,4 +27,8 @@

var options = {
views: {
it('returns view with crumb', function (done) {
var server = new Hapi.Server();
server.connection();
server.views({
path: __dirname + '/templates',

@@ -34,14 +38,10 @@ engines: {

}
}
};
});
it('returns view with crumb', function (done) {
var server1 = new Hapi.Server(options);
server1.route([
server.route([
{
method: 'GET', path: '/1', handler: function (request, reply) {
expect(request.plugins.crumb).to.exist;
expect(request.server.plugins.crumb.generate).to.exist;
expect(request.plugins.crumb).to.exist();
expect(request.server.plugins.crumb.generate).to.exist();

@@ -96,7 +96,8 @@ return reply.view('index', {

server1.pack.register({ plugin: require('../'), options: { cookieOptions: { isSecure: true } } }, function (err) {
server.register({ register: Crumb, options: { cookieOptions: { isSecure: true } } }, function (err) {
expect(err).to.not.exist;
server1.inject({ method: 'GET', url: '/1' }, function (res) {
expect(err).to.not.exist();
server.inject({ method: 'GET', url: '/1' }, function (res) {
expect(res.statusCode).to.equal(200);
var header = res.headers['set-cookie'];

@@ -109,15 +110,15 @@ expect(header.length).to.equal(1);

server1.inject({ method: 'POST', url: '/2', payload: '{ "key": "value", "crumb": "' + cookie[1] + '" }', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) {
server.inject({ method: 'POST', url: '/2', payload: '{ "key": "value", "crumb": "' + cookie[1] + '" }', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) {
expect(res.result).to.equal('valid');
server1.inject({ method: 'POST', url: '/2', payload: '{ "key": "value", "crumb": "x' + cookie[1] + '" }', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) {
server.inject({ method: 'POST', url: '/2', payload: '{ "key": "value", "crumb": "x' + cookie[1] + '" }', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) {
expect(res.statusCode).to.equal(403);
server1.inject({ method: 'POST', url: '/3', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) {
server.inject({ method: 'POST', url: '/3', headers: { cookie: 'crumb=' + cookie[1] } }, function (res) {
expect(res.statusCode).to.equal(403);
server1.inject({ method: 'GET', url: '/4' }, function (res) {
server.inject({ method: 'GET', url: '/4' }, function (res) {

@@ -135,7 +136,8 @@ expect(res.result).to.equal('<!DOCTYPE html><html><head><title>test</title></head><body><div><h1>hi</h1><h2></h2></div></body></html>');

TestStream.prototype._read = function() {
TestStream.prototype._read = function () {
var i = this._index++;
if (i > this._max)
if (i > this._max) {
this.push(null);
}
else {

@@ -148,7 +150,7 @@ var str = '' + i;

server1.inject({ method: 'POST', url: '/5', payload: new TestStream(), headers: { 'content-type': 'application/octet-stream', 'content-disposition': 'attachment; filename="test.txt"' }, simulate: { end: true } }, function (res) {
server.inject({ method: 'POST', url: '/5', payload: new TestStream(), headers: { 'content-type': 'application/octet-stream', 'content-disposition': 'attachment; filename="test.txt"' }, simulate: { end: true } }, function (res) {
expect(res.statusCode).to.equal(403);
server1.inject({method: 'GET', url: '/6'}, function(res) {
server.inject({method: 'GET', url: '/6'}, function(res) {

@@ -162,3 +164,3 @@ var header = res.headers['set-cookie'];

server1.inject({method: 'GET', url: '/7'}, function(res) {
server.inject({method: 'GET', url: '/7'}, function(res) {

@@ -169,5 +171,5 @@ var cookie = res.headers['set-cookie'].toString();

var headers = {};
headers['Origin'] = '127.0.0.1';
headers.origin = '127.0.0.1';
server1.inject({method: 'GET', url: '/1', headers: headers}, function(res) {
server.inject({method: 'GET', url: '/1', headers: headers}, function(res) {

@@ -190,10 +192,19 @@ var cookie = res.headers['set-cookie'].toString();

it('Does not add crumb to view context when "addToViewContext" option set to false', function(done) {
it('Does not add crumb to view context when "addToViewContext" option set to false', function (done) {
var server2 = new Hapi.Server(options);
server2.route({
var server = new Hapi.Server();
server.connection();
server.views({
path: __dirname + '/templates',
engines: {
html: require('handlebars')
}
});
server.route({
method: 'GET', path: '/1', handler: function (request, reply) {
expect(request.plugins.crumb).to.exist;
expect(request.server.plugins.crumb.generate).to.exist;
expect(request.plugins.crumb).to.exist();
expect(request.server.plugins.crumb.generate).to.exist();

@@ -207,6 +218,6 @@ return reply.view('index', {

server2.pack.register({ plugin: require('../'), options: { cookieOptions: { isSecure: true }, addToViewContext: false } }, function (err) {
server.register({ register: Crumb, options: { cookieOptions: { isSecure: true }, addToViewContext: false } }, function (err) {
expect(err).to.not.exist;
server2.inject({ method: 'GET', url: '/1' }, function (res) {
expect(err).to.not.exist();
server.inject({ method: 'GET', url: '/1' }, function (res) {

@@ -219,10 +230,19 @@ expect(res.result).to.equal('<!DOCTYPE html><html><head><title>test</title></head><body><div><h1>hi</h1><h2></h2></div></body></html>');

it('Works without specifying plugin options', function(done) {
it('Works without specifying plugin options', function (done) {
var server3 = new Hapi.Server(options);
server3.route({
var server = new Hapi.Server();
server.connection();
server.views({
path: __dirname + '/templates',
engines: {
html: require('handlebars')
}
});
server.route({
method: 'GET', path: '/1', handler: function (request, reply) {
expect(request.plugins.crumb).to.exist;
expect(request.server.plugins.crumb.generate).to.exist;
expect(request.plugins.crumb).to.exist();
expect(request.server.plugins.crumb.generate).to.exist();

@@ -236,7 +256,7 @@ return reply.view('index', {

server3.pack.register({ plugin: require('../'), options: null }, function (err) {
server.register({ register: Crumb, options: null }, function (err) {
expect(err).to.not.exist;
expect(err).to.not.exist();
server3.inject({ method: 'GET', url: '/1' }, function (res) {
server.inject({ method: 'GET', url: '/1' }, function (res) {

@@ -254,6 +274,15 @@ var header = res.headers['set-cookie'];

it('route uses crumb when route.config.plugins.crumb set to true and autoGenerate set to false', function(done) {
it('route uses crumb when route.config.plugins.crumb set to true and autoGenerate set to false', function (done) {
var server3 = new Hapi.Server(options);
server3.route([
var server = new Hapi.Server();
server.connection();
server.views({
path: __dirname + '/templates',
engines: {
html: require('handlebars')
}
});
server.route([
{

@@ -264,3 +293,3 @@ method: 'GET', path: '/1', handler: function (request, reply) {

expect(crumb).to.be.undefined;
expect(crumb).to.not.exist();

@@ -280,9 +309,9 @@ return reply('bonjour');

server3.pack.register({ plugin: require('../'), options: { autoGenerate: false } }, function (err) {
server.register({ register: Crumb, options: { autoGenerate: false } }, function (err) {
expect(err).to.not.exist;
expect(err).to.not.exist();
server3.inject({ method: 'GET', url: '/1' }, function (res) {
server.inject({ method: 'GET', url: '/1' }, function (res) {
server3.inject({ method: 'GET', url: '/2'}, function (res) {
server.inject({ method: 'GET', url: '/2'}, function (res) {

@@ -300,4 +329,6 @@ var header = res.headers['set-cookie'];

it('does not validate crumb when "skip" option returns true', function (done) {
var server6 = new Hapi.Server();
server6.route([
var server = new Hapi.Server();
server.connection();
server.route([
{

@@ -316,12 +347,12 @@ method: 'POST', path: '/1', handler: function (request, reply) {

server6.pack.register({ plugin: require('../'), options: { skip: skip }}, function (err) {
expect(err).to.not.exist;
server.register({ register: Crumb, options: { skip: skip }}, function (err) {
expect(err).to.not.exist();
var headers = {};
headers['X-API-Token'] = 'test';
server6.inject({ method: 'POST', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'POST', url: '/1', headers: headers }, function (res) {
expect(res.statusCode).to.equal(200);
var header = res.headers['set-cookie'];
expect(header).to.not.contain('crumb');
expect(header).to.not.exist();
done();

@@ -333,4 +364,6 @@ });

it('ensures crumb validation when "skip" option is not a function', function (done) {
var server6 = new Hapi.Server();
server6.route([
var server = new Hapi.Server();
server.connection();
server.route([
{

@@ -346,7 +379,7 @@ method: 'POST', path: '/1', handler: function (request, reply) {

server6.pack.register({ plugin: require('../'), options: { skip: skip }}, function (err) {
expect(err).to.not.exist;
server.register({ register: Crumb, options: { skip: skip }}, function (err) {
expect(err).to.not.exist();
var headers = {};
headers['X-API-Token'] = 'not-test';
server6.inject({ method: 'POST', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'POST', url: '/1', headers: headers }, function (res) {

@@ -361,33 +394,27 @@ expect(res.statusCode).to.equal(403);

it('does not allow "*" for allowOrigins setting', function (done) {
var server7 = new Hapi.Server();
server7.pack.register({ plugin: require('../'), options: { allowOrigins: ['*'] } }, function (err) {
var server = new Hapi.Server();
server.connection();
expect(err).to.exist;
expect(function () {
done();
});
server.register({ register: Crumb, options: { allowOrigins: ['*'] } }, function (err) {});
}).to.throw(/Invalid crumb options/);
done();
});
it('does not set crumb cookie insecurely', function(done) {
var options = {
cors: true
}
var server4 = new Hapi.Server("localhost", options);
server4.route([
{
method: 'GET', path: '/1', handler: function (request, reply) {
it('does not set crumb cookie insecurely', function (done) {
return reply('test');
}
}
]);
server4.pack.register({ plugin: require('../'), options: null }, function (err) {
var server = new Hapi.Server();
server.connection({ host: 'localhost', port: 80, routes: { cors: true } });
server.route({ method: 'GET', path: '/1', handler: function (request, reply) { return reply('test'); } });
expect(err).to.not.exist;
server.register({ register: Crumb, options: null }, function (err) {
expect(err).to.not.exist();
var headers = {};
headers['Host'] = 'http://localhost:80';
headers.host = 'http://localhost:80';
server4.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {

@@ -397,10 +424,10 @@ var header = res.headers['set-cookie'];

delete headers['Host'];
delete headers.host;
server4.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
headers['Origin'] = '127.0.0.1';
headers.origin = '127.0.0.1';
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();

@@ -413,5 +440,10 @@ done();

it('does not set crumb cookie insecurely using https', function(done) {
it('does not set crumb cookie insecurely using https', function (done) {
var options = {
cors: true,
host: 'localhost',
port: 443,
routes: {
cors: true
},
tls: {

@@ -421,5 +453,7 @@ key: '-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA0UqyXDCqWDKpoNQQK/fdr0OkG4gW6DUafxdufH9GmkX/zoKz\ng/SFLrPipzSGINKWtyMvo7mPjXqqVgE10LDI3VFV8IR6fnART+AF8CW5HMBPGt/s\nfQW4W4puvBHkBxWSW1EvbecgNEIS9hTGvHXkFzm4xJ2e9DHp2xoVAjREC73B7JbF\nhc5ZGGchKw+CFmAiNysU0DmBgQcac0eg2pWoT+YGmTeQj6sRXO67n2xy/hA1DuN6\nA4WBK3wM3O4BnTG0dNbWUEbe7yAbV5gEyq57GhJIeYxRvveVDaX90LoAqM4cUH06\n6rciON0UbDHV2LP/JaH5jzBjUyCnKLLo5snlbwIDAQABAoIBAQDJm7YC3pJJUcxb\nc8x8PlHbUkJUjxzZ5MW4Zb71yLkfRYzsxrTcyQA+g+QzA4KtPY8XrZpnkgm51M8e\n+B16AcIMiBxMC6HgCF503i16LyyJiKrrDYfGy2rTK6AOJQHO3TXWJ3eT3BAGpxuS\n12K2Cq6EvQLCy79iJm7Ks+5G6EggMZPfCVdEhffRm2Epl4T7LpIAqWiUDcDfS05n\nNNfAGxxvALPn+D+kzcSF6hpmCVrFVTf9ouhvnr+0DpIIVPwSK/REAF3Ux5SQvFuL\njPmh3bGwfRtcC5d21QNrHdoBVSN2UBLmbHUpBUcOBI8FyivAWJhRfKnhTvXMFG8L\nwaXB51IZAoGBAP/E3uz6zCyN7l2j09wmbyNOi1AKvr1WSmuBJveITouwblnRSdvc\nsYm4YYE0Vb94AG4n7JIfZLKtTN0xvnCo8tYjrdwMJyGfEfMGCQQ9MpOBXAkVVZvP\ne2k4zHNNsfvSc38UNSt7K0HkVuH5BkRBQeskcsyMeu0qK4wQwdtiCoBDAoGBANF7\nFMppYxSW4ir7Jvkh0P8bP/Z7AtaSmkX7iMmUYT+gMFB5EKqFTQjNQgSJxS/uHVDE\nSC5co8WGHnRk7YH2Pp+Ty1fHfXNWyoOOzNEWvg6CFeMHW2o+/qZd4Z5Fep6qCLaa\nFvzWWC2S5YslEaaP8DQ74aAX4o+/TECrxi0z2lllAoGAdRB6qCSyRsI/k4Rkd6Lv\nw00z3lLMsoRIU6QtXaZ5rN335Awyrfr5F3vYxPZbOOOH7uM/GDJeOJmxUJxv+cia\nPQDflpPJZU4VPRJKFjKcb38JzO6C3Gm+po5kpXGuQQA19LgfDeO2DNaiHZOJFrx3\nm1R3Zr/1k491lwokcHETNVkCgYBPLjrZl6Q/8BhlLrG4kbOx+dbfj/euq5NsyHsX\n1uI7bo1Una5TBjfsD8nYdUr3pwWltcui2pl83Ak+7bdo3G8nWnIOJ/WfVzsNJzj7\n/6CvUzR6sBk5u739nJbfgFutBZBtlSkDQPHrqA7j3Ysibl3ZIJlULjMRKrnj6Ans\npCDwkQKBgQCM7gu3p7veYwCZaxqDMz5/GGFUB1My7sK0hcT7/oH61yw3O8pOekee\nuctI1R3NOudn1cs5TAy/aypgLDYTUGQTiBRILeMiZnOrvQQB9cEf7TFgDoRNCcDs\nV/ZWiegVB/WY7H0BkCekuq5bHwjgtJTpvHGqQ9YD7RhE8RSYOhdQ/Q==\n-----END RSA PRIVATE KEY-----\n',

}
}
var server4 = new Hapi.Server("localhost", options);
server4.route([
};
var server = new Hapi.Server();
server.connection(options);
server.route([
{

@@ -432,23 +466,14 @@ method: 'GET', path: '/1', handler: function (request, reply) {

]);
server4.pack.register({ plugin: require('../'), options: null }, function (err) {
server.register({ register: Crumb, options: null }, function (err) {
expect(err).to.not.exist;
expect(err).to.not.exist();
var headers = {};
headers['Host'] = 'https://localhost:443';
server.inject({ method: 'GET', url: '/1', headers: { host: 'https://localhost:443' } }, function (res) {
server4.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header[0]).to.contain('crumb');
delete headers['Host'];
server.inject({ method: 'GET', url: '/1' }, function (res) {
server4.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
headers['Origin'] = '127.0.0.1';
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(res.headers['set-cookie']).to.not.exist();
done();

@@ -460,8 +485,7 @@ });

it('does set crumb cookie if allowOrigins set and CORS enabled', function(done) {
var options = {
cors: true
}
var server5 = new Hapi.Server(options);
server5.route([
it('does set crumb cookie if allowOrigins set and CORS enabled', function (done) {
var server = new Hapi.Server();
server.connection({ host: 'localhost', port: 80, routes: { cors: true } });
server.route([
{

@@ -474,7 +498,7 @@ method: 'GET', path: '/1', handler: function (request, reply) {

]);
server5.pack.register({ plugin: require('../'), options: { allowOrigins: ['127.0.0.1']} }, function (err) {
expect(err).to.not.exist;
server.register({ register: Crumb, options: { allowOrigins: ['127.0.0.1']} }, function (err) {
expect(err).to.not.exist();
var headers = {};
headers['Origin'] = '127.0.0.1';
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
headers.origin = '127.0.0.1';
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {

@@ -484,22 +508,22 @@ var header = res.headers['set-cookie'];

headers['Origin'] = '127.0.0.2';
headers.origin = '127.0.0.2';
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();
headers['Origin'] = '127.0.0.1:2000';
headers.origin = '127.0.0.1:2000';
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();
delete headers['Origin'];
delete headers.origin;
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();

@@ -514,10 +538,7 @@ done();

it('does set crumb cookie if allowOrigins not set and CORS enabled with server.settings.cors.origin set', function(done) {
var options = {
cors: {
origin: ['127.0.0.1']
}
}
var server5 = new Hapi.Server(options);
server5.route([
it('does set crumb cookie if allowOrigins not set and CORS enabled with server.settings.cors.origin set', function (done) {
var server = new Hapi.Server();
server.connection({ host: 'localhost', port: 80, routes: { cors: { origin: ['127.0.0.1'] } } });
server.route([
{

@@ -530,7 +551,7 @@ method: 'GET', path: '/1', handler: function (request, reply) {

]);
server5.pack.register({ plugin: require('../'), options: null }, function (err) {
expect(err).to.not.exist;
server.register({ register: Crumb, options: null }, function (err) {
expect(err).to.not.exist();
var headers = {};
headers['Origin'] = '127.0.0.1';
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
headers.origin = '127.0.0.1';
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {

@@ -540,22 +561,22 @@ var header = res.headers['set-cookie'];

headers['Origin'] = '127.0.0.2';
headers.origin = '127.0.0.2';
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();
headers['Origin'] = '127.0.0.1:2000';
headers.origin = '127.0.0.1:2000';
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();
delete headers['Origin'];
delete headers.origin;
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();

@@ -570,11 +591,7 @@ done();

it('does not set crumb cookie if allowOrigins not set and CORS set to "*"', function(done) {
it('does not set crumb cookie if allowOrigins not set and CORS set to "*"', function (done) {
var options = {
cors: {
origin: ['*']
}
}
var server5 = new Hapi.Server(options);
server5.route([
var server = new Hapi.Server();
server.connection({ host: 'localhost', port: 80, routes: { cors: { origin: ['*'] } } });
server.route([
{

@@ -588,10 +605,10 @@ method: 'GET', path: '/1', handler: function (request, reply) {

server5.pack.register({ plugin: require('../'), options: null }, function (err) {
expect(err).to.not.exist;
server.register({ register: Crumb, options: null }, function (err) {
expect(err).to.not.exist();
var headers = {};
headers['Origin'] = '127.0.0.1';
server5.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
headers.origin = '127.0.0.1';
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();

@@ -604,7 +621,6 @@ done();

it('checks port for allowOrigins setting', function (done) {
var options = {
cors: true
}
var server8 = new Hapi.Server(options);
server8.route([
var server = new Hapi.Server();
server.connection({ host: 'localhost', port: 80, routes: { cors: true } });
server.route([
{

@@ -617,7 +633,7 @@ method: 'GET', path: '/1', handler: function (request, reply) {

]);
server8.pack.register({ plugin: require('../'), options: { allowOrigins: ['127.0.0.1:2000']} }, function (err) {
expect(err).to.not.exist;
server.register({ register: Crumb, options: { allowOrigins: ['127.0.0.1:2000']} }, function (err) {
expect(err).to.not.exist();
var headers = {};
headers['Origin'] = '127.0.0.1:2000';
server8.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
headers.origin = '127.0.0.1:2000';
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {

@@ -627,13 +643,13 @@ var header = res.headers['set-cookie'];

headers['Origin'] = '127.0.0.1:1000';
server8.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
headers.origin = '127.0.0.1:1000';
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();
headers['Origin'] = '127.0.0.1';
server8.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
headers.origin = '127.0.0.1';
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();

@@ -648,7 +664,6 @@ done();

it('parses wildcards in allowOrigins setting', function (done) {
var options = {
cors: true
}
var server9 = new Hapi.Server(options);
server9.route([
var server = new Hapi.Server();
server.connection({ host: 'localhost', port: 80, routes: { cors: true } });
server.route([
{

@@ -661,7 +676,7 @@ method: 'GET', path: '/1', handler: function (request, reply) {

]);
server9.pack.register({ plugin: require('../'), options: { allowOrigins: ['127.0.0.1:*', '*.test.com']} }, function (err) {
expect(err).to.not.exist;
server.register({ register: Crumb, options: { allowOrigins: ['127.0.0.1:*', '*.test.com']} }, function (err) {
expect(err).to.not.exist();
var headers = {};
headers['Origin'] = '127.0.0.1:2000';
server9.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
headers.origin = '127.0.0.1:2000';
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {

@@ -671,4 +686,4 @@ var header = res.headers['set-cookie'];

headers['Origin'] = 'foo.test.com';
server9.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
headers.origin = 'foo.test.com';
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {

@@ -678,12 +693,11 @@ //expect(header[0]).to.contain('crumb');

headers['Origin'] = 'foo.tesc.com';
headers.origin = 'foo.tesc.com';
server9.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
server.inject({ method: 'GET', url: '/1', headers: headers }, function (res) {
var header = res.headers['set-cookie'];
expect(header).to.be.undefined;
expect(header).to.not.exist();
done();
});
});

@@ -690,0 +704,0 @@ });

// Load modules
var Code = require('code');
var Crumb = require('../');
var Hapi = require('hapi');
var Lab = require('lab');
var Hapi = require('hapi');
var Crumb = require('../');

@@ -15,7 +16,6 @@

var expect = Lab.expect;
var before = Lab.before;
var after = Lab.after;
var describe = Lab.experiment;
var it = Lab.test;
var lab = exports.lab = Lab.script();
var describe = lab.describe;
var it = lab.it;
var expect = Code.expect;

@@ -27,13 +27,12 @@

var options = {
views: {
path: __dirname + '/templates',
engines: {
html: require('handlebars')
}
var server = new Hapi.Server();
server.connection();
server.views({
path: __dirname + '/templates',
engines: {
html: require('handlebars')
}
};
});
var server = new Hapi.Server(options);
server.route([

@@ -43,4 +42,4 @@ {

expect(request.plugins.crumb).to.exist;
expect(request.server.plugins.crumb.generate).to.exist;
expect(request.plugins.crumb).to.exist();
expect(request.server.plugins.crumb.generate).to.exist();

@@ -103,5 +102,5 @@ return reply.view('index', {

server.pack.register({plugin: require('../'), options: { restful: true, cookieOptions: { isSecure: true } } }, function (err) {
server.register({ register: Crumb, options: { restful: true, cookieOptions: { isSecure: true } } }, function (err) {
expect(err).to.not.exist;
expect(err).to.not.exist();
server.inject({ method: 'GET', url: '/1' }, function (res) {

@@ -116,7 +115,7 @@

var validHeader = {};
validHeader['cookie'] = 'crumb=' + cookie[1];
validHeader.cookie = 'crumb=' + cookie[1];
validHeader['x-csrf-token'] = cookie[1];
var invalidHeader = {};
invalidHeader['cookie'] = 'crumb=' + cookie[1];
invalidHeader.cookie = 'crumb=' + cookie[1];
invalidHeader['x-csrf-token'] = 'x' + cookie[1];

@@ -188,3 +187,1 @@

});

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