From ad6646683f320329779a6aa8eb61a1ae6c42255e Mon Sep 17 00:00:00 2001 From: reggi Date: Wed, 29 Jan 2025 11:46:23 -0500 Subject: [PATCH 1/2] fix(server): redactThrow should return function --- lib/server.js | 12 +++++++----- test/server.js | 11 +++++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/server.js b/lib/server.js index 41f3f40..d8bf262 100644 --- a/lib/server.js +++ b/lib/server.js @@ -41,14 +41,16 @@ function redactError (input) { } /** runs a function within try / catch and throws error wrapped in redactError */ -async function redactThrow (func) { +function redactThrow (func) { if (typeof func !== 'function') { throw new Error('redactThrow expects a function') } - try { - return await func() - } catch (error) { - throw redactError(error) + return async (...args) => { + try { + return await func(...args) + } catch (error) { + throw redactError(error) + } } } diff --git a/test/server.js b/test/server.js index c03281a..dc130ba 100644 --- a/test/server.js +++ b/test/server.js @@ -79,10 +79,13 @@ t.test('redactThrow', async t => { await t.test('successfully throws error', async t => { const badError = new CustomError('hello world', 'sensitive data') t.same(badError.sensitive, 'sensitive data', 'should have sensitive field') + + const handler = async () => { + throw badError + } + const safeHandler = redactThrow(handler) try { - await redactThrow(async () => { - throw badError - }) + await safeHandler() t.fail('should throw') } catch (goodError) { t.same(goodError.sensitive, undefined, 'should not have sensitive field') @@ -90,7 +93,7 @@ t.test('redactThrow', async t => { }) t.test('invalid argument not function', async t => { try { - await redactThrow('hello world') + redactThrow('hello world') t.fail('should throw') } catch (error) { t.same(error.message, 'redactThrow expects a function', 'should throw with correct message') From 0fb1b4a84f4d2eafe7eb2e2f5c24afeedb7e8dd4 Mon Sep 17 00:00:00 2001 From: reggi Date: Mon, 21 Apr 2025 12:04:02 -0400 Subject: [PATCH 2/2] redacts cookie header --- lib/matchers.js | 7 +++++++ lib/server.js | 2 ++ test/server.js | 14 ++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/lib/matchers.js b/lib/matchers.js index fe9b907..854ba8e 100644 --- a/lib/matchers.js +++ b/lib/matchers.js @@ -44,6 +44,12 @@ const DEEP_HEADER_SET_COOKIE = { replacement: '[REDACTED_HEADER_SET_COOKIE]', } +const DEEP_HEADER_COOKIE = { + type: TYPE_PATH, + predicate: ({ path }) => path.endsWith('.headers.cookie'), + replacement: '[REDACTED_HEADER_COOKIE]', +} + const REWRITE_REQUEST = { type: TYPE_PATH, predicate: ({ path }) => path.endsWith('.request'), @@ -76,6 +82,7 @@ module.exports = { URL_MATCHER, DEEP_HEADER_AUTHORIZATION, DEEP_HEADER_SET_COOKIE, + DEEP_HEADER_COOKIE, REWRITE_REQUEST, REWRITE_RESPONSE, } diff --git a/lib/server.js b/lib/server.js index d8bf262..555e37d 100644 --- a/lib/server.js +++ b/lib/server.js @@ -6,6 +6,7 @@ const { DEEP_HEADER_SET_COOKIE, REWRITE_REQUEST, REWRITE_RESPONSE, + DEEP_HEADER_COOKIE, } = require('./matchers') const { @@ -24,6 +25,7 @@ const _redact = redactMatchers( JSON_WEB_TOKEN, DEEP_HEADER_AUTHORIZATION, DEEP_HEADER_SET_COOKIE, + DEEP_HEADER_COOKIE, REWRITE_REQUEST, REWRITE_RESPONSE, redactUrlMatcher( diff --git a/test/server.js b/test/server.js index dc130ba..0f6f42e 100644 --- a/test/server.js +++ b/test/server.js @@ -111,3 +111,17 @@ t.test('serialize a redactError', async t => { t.same(goodError.stack, badError.stack, 'should serialize stack') t.same(serialized.sensitive, undefined, 'should not serialize sensitive data') }) + +t.test('readcts header.cookie', async t => { + const input = { + headers: { + cookie: examples.COOKIE, + }, + } + const output = redact(input) + t.same(output, { + headers: { + cookie: matchers.DEEP_HEADER_COOKIE.replacement, + }, + }) +})