diff --git a/packages/ecs-morgan-format/index.js b/packages/ecs-morgan-format/index.js index b3d2da7..ac32c4b 100644 --- a/packages/ecs-morgan-format/index.js +++ b/packages/ecs-morgan-format/index.js @@ -24,6 +24,7 @@ const { formatHttpRequest, formatHttpResponse } = require('@elastic/ecs-helpers') +const fastRedact = require('fast-redact'); // We will query the Elastic APM agent if it is available. let elasticApm = null @@ -64,6 +65,7 @@ const stringify = safeStableStringify.configure({ deterministic: false }) // The former allows specifying other options. function ecsFormat (opts) { let format = morgan.combined + let redactPaths = []; let apmIntegration = true if (opts && typeof opts === 'object') { // Usage: ecsFormat({ /* opts */ }) @@ -73,6 +75,9 @@ function ecsFormat (opts) { if (opts.apmIntegration != null) { apmIntegration = opts.apmIntegration } + if (opts.redactPaths != null && Array.isArray(opts.redactPaths) && opts.redactPaths.length > 0) { + redactPaths = opts.redactPaths; + } } else if (opts) { // Usage: ecsFormat(format) format = opts @@ -175,6 +180,16 @@ function ecsFormat (opts) { formatHttpRequest(ecsFields, req) formatHttpResponse(ecsFields, res) + if (redactPaths.length > 0) { + const fastRedactOpts = { + paths: opts.redactPaths, + serialize: false, + }; + const redact = fastRedact(fastRedactOpts); + + redact(ecsFields); + } + return stringify(ecsFields) } } diff --git a/packages/ecs-morgan-format/package.json b/packages/ecs-morgan-format/package.json index 0eb646c..60cb160 100644 --- a/packages/ecs-morgan-format/package.json +++ b/packages/ecs-morgan-format/package.json @@ -41,6 +41,7 @@ }, "dependencies": { "@elastic/ecs-helpers": "^2.1.1", + "fast-redact": "^3.5.0", "safe-stable-stringify": "^2.4.3" }, "devDependencies": { diff --git a/packages/ecs-morgan-format/test/basic.test.js b/packages/ecs-morgan-format/test/basic.test.js index 090986e..13f5298 100644 --- a/packages/ecs-morgan-format/test/basic.test.js +++ b/packages/ecs-morgan-format/test/basic.test.js @@ -235,3 +235,20 @@ test('can configure correlation fields', t => { t.end() }) }) + +test('redact authorization', t => { + const stream = split().on('data', line => { + const rec = JSON.parse(line) + const test = rec.http.request.headers.authorization; + t.equal(test, '[REDACTED]') + }) + const logger = morgan(ecsFormat({ + format: 'tiny', + redactPaths: ['http.request.headers.authorization'], + }), { stream }) + + makeExpressServerAndRequest(logger, '/?foo=bar', { method: 'POST', headers: { authorization: 'Bearer gjfkgkdfgkjdfk' } }, 'hi', function (err) { + t.error(err) + t.end() + }) +})