+15
-3
@@ -24,3 +24,4 @@ 'use strict'; | ||
| restful: Joi.boolean().optional(), | ||
| skip: Joi.func().optional() | ||
| skip: Joi.func().optional(), | ||
| logUnauthorized: Joi.boolean().optional() | ||
| }); | ||
@@ -38,3 +39,4 @@ | ||
| restful: false, // Set to true for X-CSRF-Token header crumb validation. Disables payload/query validation | ||
| skip: false // Set to a function which returns true when to skip crumb generation and validation | ||
| skip: false, // Set to a function which returns true when to skip crumb generation and validation | ||
| logUnauthorized: false // Set to true for crumb to write an event to the request log | ||
| }; | ||
@@ -62,2 +64,9 @@ | ||
| const unauthorizedLogger = () => { | ||
| if (settings.logUnauthorized) { | ||
| request.log(['crumb', 'unauthorized'], 'validation failed'); | ||
| } | ||
| }; | ||
| // If skip function enabled. Call it and if returns true, do not attempt to do anything with crumb. | ||
@@ -107,3 +116,3 @@ | ||
| if (!content || content instanceof Stream) { | ||
| unauthorizedLogger(); | ||
| return reply(Boom.forbidden()); | ||
@@ -113,2 +122,3 @@ } | ||
| if (content[request.route.settings.plugins._crumb.key] !== request.plugins.crumb) { | ||
| unauthorizedLogger(); | ||
| return reply(Boom.forbidden()); | ||
@@ -131,2 +141,3 @@ } | ||
| if (!header) { | ||
| unauthorizedLogger(); | ||
| return reply(Boom.forbidden()); | ||
@@ -136,2 +147,3 @@ } | ||
| if (header !== request.plugins.crumb) { | ||
| unauthorizedLogger(); | ||
| return reply(Boom.forbidden()); | ||
@@ -138,0 +150,0 @@ } |
+2
-2
| { | ||
| "name": "crumb", | ||
| "description": "CSRF crumb generation and validation plugin", | ||
| "version": "6.0.3", | ||
| "version": "6.1.0", | ||
| "repository": "git://github.com/hapijs/crumb", | ||
@@ -32,3 +32,3 @@ "bugs": { | ||
| "handlebars": "^4.0.5", | ||
| "hapi": "13.x.x", | ||
| "hapi": "16.x.x", | ||
| "lab": "10.x.x", | ||
@@ -35,0 +35,0 @@ "vision": "^4.0.0" |
+1
-0
@@ -34,2 +34,3 @@  | ||
| * 'skip' - a function with the signature of `function (request, reply) {}`, which when provided, is called for every request. If the provided function returns true, validation and generation of crumb is skipped (defaults to false) | ||
| * 'logUnauthorized' - whether to add to the request log with tag 'crumb' and data 'validation failed' (defaults to false) | ||
@@ -36,0 +37,0 @@ Additionally, some configuration can be passed on a per-route basis |
+109
-0
@@ -273,2 +273,111 @@ 'use strict'; | ||
| it('Adds to the request log if plugin option logUnauthorized is set to true', (done) => { | ||
| const server = new Hapi.Server(); | ||
| server.connection(); | ||
| let logFound; | ||
| const preResponse = function (request, reply) { | ||
| const logs = request.getLog(); | ||
| logFound = logs.find((log) => { | ||
| return log.tags[0] === 'crumb' && log.data === 'validation failed'; | ||
| }); | ||
| return reply.continue(); | ||
| }; | ||
| server.ext('onPreResponse', preResponse); | ||
| server.route({ | ||
| method: 'POST', | ||
| path: '/1', | ||
| config: { | ||
| log: true | ||
| }, | ||
| handler: (request, reply) => { | ||
| return reply('test'); | ||
| } | ||
| }); | ||
| server.register([ | ||
| { | ||
| register: Crumb, | ||
| options: { | ||
| logUnauthorized: true | ||
| } | ||
| } | ||
| ], () => { | ||
| const headers = {}; | ||
| headers['X-API-Token'] = 'test'; | ||
| server.inject({ | ||
| method: 'POST', | ||
| url: '/1', | ||
| headers | ||
| }, () => { | ||
| expect(logFound).to.exist(); | ||
| done(); | ||
| }); | ||
| }); | ||
| }); | ||
| it('Does not add to the request log if plugin option logUnauthorized is set to false', (done) => { | ||
| const server = new Hapi.Server(); | ||
| server.connection(); | ||
| let logFound; | ||
| const preResponse = function (request, reply) { | ||
| const logs = request.getLog(); | ||
| logFound = logs.find((log) => { | ||
| return log.tags[0] === 'crumb' && log.data === 'validation failed'; | ||
| }); | ||
| return reply.continue(); | ||
| }; | ||
| server.ext('onPreResponse', preResponse); | ||
| server.route({ | ||
| method: 'POST', | ||
| path: '/1', | ||
| config: { | ||
| log: true | ||
| }, | ||
| handler: (request, reply) => { | ||
| return reply('test'); | ||
| } | ||
| }); | ||
| server.register([ | ||
| { | ||
| register: Crumb, | ||
| options: { | ||
| logUnauthorized: false | ||
| } | ||
| } | ||
| ], () => { | ||
| const headers = {}; | ||
| headers['X-API-Token'] = 'test'; | ||
| server.inject({ | ||
| method: 'POST', | ||
| url: '/1' | ||
| }, () => { | ||
| expect(logFound).to.not.exist(); | ||
| done(); | ||
| }); | ||
| }); | ||
| }); | ||
| it('should fail to register with bad options', (done) => { | ||
@@ -275,0 +384,0 @@ |
Sorry, the diff of this file is not supported yet
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
109117
2.84%790
13.51%41
2.5%14
-6.67%