From 555eadf1e482c525b465daccb01a5fc593bd1c8d Mon Sep 17 00:00:00 2001 From: Ian Fox Date: Tue, 11 Jul 2017 17:53:33 -0700 Subject: [PATCH] fix(tokens): don't show tokens in server logs --- plugins/logging.js | 3 ++- plugins/tokens/filter.js | 10 ++++++++++ test/plugins/tokens.test.js | 28 ++++++++++++++++++++++++---- 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 plugins/tokens/filter.js diff --git a/plugins/logging.js b/plugins/logging.js index 457f952eb..8083f7fd6 100644 --- a/plugins/logging.js +++ b/plugins/logging.js @@ -1,6 +1,7 @@ 'use strict'; const good = require('good'); +const suppressAPITokens = require('./tokens/filter'); module.exports = { register: good, @@ -15,7 +16,7 @@ module.exports = { args: [{ error: '*', log: '*', response: '*', request: '*' }] }, { module: 'good-console' - }, 'stdout'] + }, suppressAPITokens, 'stdout'] } } }; diff --git a/plugins/tokens/filter.js b/plugins/tokens/filter.js new file mode 100644 index 000000000..fadbc37d5 --- /dev/null +++ b/plugins/tokens/filter.js @@ -0,0 +1,10 @@ +'use strict'; + +const { Transform } = require('stream'); +const tokenRegex = /(^|[^a-zA-Z0-9_-])[a-zA-Z0-9_-]{43}([^a-zA-Z0-9_-]|$)/g; + +module.exports = new Transform({ + transform(chunk, encoding, callback) { + callback(null, chunk.toString().replace(tokenRegex, '$1(API Token Suppressed)$2')); + } +}); diff --git a/test/plugins/tokens.test.js b/test/plugins/tokens.test.js index b2f3db41f..daf2feb73 100644 --- a/test/plugins/tokens.test.js +++ b/test/plugins/tokens.test.js @@ -1,12 +1,16 @@ 'use strict'; -const assert = require('chai').assert; -const sinon = require('sinon'); +const { assert } = require('chai'); const hapi = require('hapi'); const mockery = require('mockery'); +const { PassThrough } = require('stream'); +const sinon = require('sinon'); +const suppressAPITokens = require('../../plugins/tokens/filter'); const urlLib = require('url'); + const testToken = require('./data/token.json'); -const testTokenWithValue = Object.assign({}, testToken, { value: '1234' }); +const testValue = '1234123412341234123412341234123412341234123'; +const testTokenWithValue = Object.assign({}, testToken, { value: testValue }); delete testTokenWithValue.hash; @@ -141,7 +145,7 @@ describe('token plugin test', () => { }); it('returns 201 and correct token data', () => { - tokenMock = getTokenMock(Object.assign({}, testToken, { value: '1234' })); + tokenMock = getTokenMock(testTokenWithValue); tokenFactoryMock.create.resolves(tokenMock); return server.inject(options).then((reply) => { @@ -436,4 +440,20 @@ describe('token plugin test', () => { }); }); }); + + describe('Logging suppresses API tokens', () => { + it('does not print API tokens in logs', (done) => { + const source = new PassThrough({ objectMode: true }); + const result = new PassThrough({ objectMode: true }); + + source.write(`This is a string with a token in it! ${testTokenWithValue.value}`); + + source.pipe(suppressAPITokens).pipe(result); + + result.on('data', (chunk) => { + assert.equal(chunk, 'This is a string with a token in it! (API Token Suppressed)'); + done(); + }); + }); + }); });