diff --git a/README.md b/README.md index 00174b4..9184386 100644 --- a/README.md +++ b/README.md @@ -79,32 +79,3 @@ you can skip this (not recommanded) by setting the environment variable In addition, you can update the pattern on which to make the match with the environment variable `LOGGER_SENSITIVE_DATA_PATTERN`. Its value must represent a valid [capturing regular expression](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/RegExp#group_back). - -You also can add custom filter : -``` -const sensitiveDataFragment = '(pass|password)'; // Will obfuscate 'pass' and 'password' data - -const newLogger = init({ - logger: { - sensitiveDataFragment, - }, -}); -``` - -Moreover, you can add customize the way it replaces data : -``` -const sensitiveDataPattern = [ - { - regex: YOUR_NEW_REGEX, - substitute: SUBSTITUTION_CONTENT, - } -]; // Will replace data matching with new regex by substitute content - -const newLogger = init({ - logger: { - sensitiveDataPattern, - }, -}); -``` - -🚨 Process is synchronous, it means that `sensitiveDataPattern` can produce performance issues on large sizes. diff --git a/index.js b/index.js index b5ba61a..e2c6a01 100644 --- a/index.js +++ b/index.js @@ -49,10 +49,7 @@ function init(config) { } else if (finalConfig.logger.hideSensitiveData) { loggerConfig.streams.push({ level: loggerLevel, - stream: new SensitiveDataStream( - finalConfig.logger.sensitiveDataFragment, - finalConfig.logger.sensitiveDataPattern - ), + stream: new SensitiveDataStream(finalConfig.logger.sensitiveDataPattern), }); } else { loggerConfig.streams.push({ level: loggerLevel, stream: process.stdout }); diff --git a/package.json b/package.json index f679e35..bca0c7a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chpr-logger", - "version": "4.2.0", + "version": "3.2.0", "description": "Logger for NodeJS application stack", "main": "index.js", "directories": { diff --git a/streams/sensitive-data.js b/streams/sensitive-data.js index d4f5a0c..db8906b 100644 --- a/streams/sensitive-data.js +++ b/streams/sensitive-data.js @@ -4,27 +4,12 @@ const DEFAULT_SENSITIVE_DATA_FRAGMENTS = '(mdp|password|authorization|token|pwd|auth)'; module.exports = class SensitiveDataStream { - constructor(fragments, patterns = []) { + constructor(fragments) { this.fragments = fragments || DEFAULT_SENSITIVE_DATA_FRAGMENTS; - this.replacer = '__SENSITIVE_DATA__'; - - this.patterns = [ - ...patterns, - { - // Default pattern - regex: new RegExp(`"${this.fragments}":"([^"]*)"`, 'ig'), // @Match "mdp":"My super password" - substitute: `"$1":"${this.replacer}"`, - }, - ]; + this.pattern = new RegExp(`"${this.fragments}":"([^"]*)"`, 'ig'); } - write(input) { - let sanitized = input; - - // Apply replace on input looping through patterns array - for (let pattern of this.patterns) { - sanitized = sanitized.replace(pattern.regex, pattern.substitute); - } + const sanitized = input.replace(this.pattern, '"$1":"__SENSITIVE_DATA__"'); return process.stdout.write(sanitized); } diff --git a/test/index.test.js b/test/index.test.js index a8a639f..baf6546 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -154,64 +154,15 @@ describe('index.js', () => { req: { token: 'My personal token', }, - cmd: 'command docker build password=test', }, 'Logging amazingly sensitive data!' ); - - const message = logs.shift(); - - expect(message.password).to.equal('__SENSITIVE_DATA__'); - expect(message.headers['accept-language']).to.equal('fr-FR'); - expect(message.headers.authorization).to.equal('__SENSITIVE_DATA__'); - expect(message.req.token).to.equal('__SENSITIVE_DATA__'); - }); - - it('should replace good parts of string using custom replacement & fragment patterns', () => { - const sensitiveDataPattern = [ - { - regex: new RegExp(`(password)=([\\w-]*)`, 'ig'), - substitute: `$1=__SENSITIVE_DATA__`, - }, - ]; - - const newLogger = init({ - logger: { sensitiveDataPattern }, - }); - - newLogger.info( - { - password: 'My personal password', - pass: 'My other personal password', - headers: { - 'accept-language': 'fr-FR', // unchanged - authorization: 'Bearer token', - }, - req: { - token: 'My personal token', - }, - cmd: - 'command docker build --build-arg password=test-1234-abcd --build-arg password=test1234-abcd --build-arg password=TEST-1234-abcd ', - cmd2: 'command docker build --build-arg password=test', - }, - 'Logging amazingly sensitive data!' - ); - const message = logs.shift(); - // Default cases expect(message.password).to.equal('__SENSITIVE_DATA__'); expect(message.headers['accept-language']).to.equal('fr-FR'); expect(message.headers.authorization).to.equal('__SENSITIVE_DATA__'); expect(message.req.token).to.equal('__SENSITIVE_DATA__'); - - // Custom cases - expect(message.cmd).to.equal( - 'command docker build --build-arg password=__SENSITIVE_DATA__ --build-arg password=__SENSITIVE_DATA__ --build-arg password=__SENSITIVE_DATA__ ' - ); - expect(message.cmd2).to.equal( - 'command docker build --build-arg password=__SENSITIVE_DATA__' - ); }); }); }); @@ -231,7 +182,7 @@ describe('index.js', () => { it('should use the sensitive data stream with specific pattern fragments if set', () => { const newLogger = init({ - logger: { sensitiveDataFragment: '(password)' }, + logger: { sensitiveDataPattern: '(password)' }, }); expect(newLogger.streams).to.have.lengthOf(1); @@ -241,32 +192,6 @@ describe('index.js', () => { expect(newLogger.streams[0].stream.fragments).to.equal('(password)'); }); - it('should use the sensitive data stream with specific replacement patterns if set', () => { - const sensitiveDataPattern = [ - { - regex: new RegExp(`(testing_string)=([\\w-]*)`, 'ig'), - substitute: `"$1":"__TESTING_REPLACEMENT__"`, - }, - ]; - - const newLogger = init({ - logger: { sensitiveDataPattern }, - }); - - expect(newLogger.streams).to.have.lengthOf(1); - expect(newLogger.streams[0]).to.have.property('stream'); - - expect(newLogger.streams[0].stream).to.be.instanceOf(SensitiveDataStream); - expect(newLogger.streams[0].stream.patterns).to.have.lengthOf(2); // New pattern & default one - expect(newLogger.streams[0].stream.patterns[0]).to.deep.equal( - // Test the 1st pattern (the other one is the default one) - { - regex: /(testing_string)=([\w-]*)/gi, - substitute: `"$1":"__TESTING_REPLACEMENT__"`, - } - ); - }); - it('should use only the default stdout stream if LOGGER_USE_SENSITIVE_DATA_STREAM is false', () => { const newLogger = init({ logger: { hideSensitiveData: false },