Skip to content

Commit e909b9b

Browse files
committed
chore(mongodb-redact): redact special character cases for password MONGOSH-2991
1 parent 525b215 commit e909b9b

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

packages/mongodb-redact/src/secrets.spec.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,57 @@ describe('dictionary-based secret redaction', function () {
9393
usr: '<user>',
9494
});
9595
});
96+
97+
describe('special characters in passwords', function () {
98+
it('redacts passwords at start, end, or entire string', function () {
99+
expect(
100+
redact('!start is pwd', [{ value: '!start', kind: 'password' }]),
101+
).to.equal('<password> is pwd');
102+
103+
expect(
104+
redact('pwd is end!', [{ value: 'end!', kind: 'password' }]),
105+
).to.equal('pwd is <password>');
106+
107+
expect(
108+
redact('The password is !@#$%', [{ value: '!@#$%', kind: 'password' }]),
109+
).to.equal('The password is <password>');
110+
});
111+
112+
it('redacts a special-character only connection string', function () {
113+
const secret = '!#!!';
114+
const content = 'Connection string: mongodb://user:!#!!@localhost:27017/';
115+
116+
const redacted = redact(content, [{ value: secret, kind: 'password' }]);
117+
118+
expect(redacted).to.equal(
119+
'Connection string: <mongodb uri><password>@localhost:27017/',
120+
);
121+
});
122+
123+
for (const { char, password } of [
124+
{ char: '.', password: 'test.pass' },
125+
{ char: '*', password: 'test*pass' },
126+
{ char: '+', password: 'test+pass' },
127+
{ char: '?', password: 'test?pass' },
128+
{ char: '[', password: 'test[123]' },
129+
{ char: '(', password: 'test(abc)' },
130+
{ char: '|', password: 'test|pass' },
131+
{ char: '\\', password: 'test\\pass' },
132+
{ char: '^', password: '^test123' },
133+
{ char: '$', password: 'test$123' },
134+
{ char: '@', password: 'user@123' },
135+
{ char: '#', password: 'pass#word' },
136+
{ char: '%', password: 'test%20' },
137+
{ char: '&', password: 'rock&roll' },
138+
{ char: 'լավ', password: 'լավ' },
139+
]) {
140+
it(`redacts passwords with ${char}`, function () {
141+
const content = `pwd: ${password} end`;
142+
const redacted = redact(content, [
143+
{ value: password, kind: 'password' },
144+
]);
145+
expect(redacted).to.equal('pwd: <password> end');
146+
});
147+
}
148+
});
96149
});

packages/mongodb-redact/src/secrets.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ export function redactSecretsOnString<T extends string>(
3232
);
3333
}
3434

35-
const regex = new RegExp(`\\b${escape(value)}\\b`, 'g');
35+
// Escape the value for use in regex and use negative lookahead/lookbehind
36+
// to match secrets not surrounded by word characters
37+
const escapedValue = escape(value);
38+
const regex = new RegExp(`(?<!\\w)${escapedValue}(?!\\w)`, 'g');
3639
result = result.replace(regex, `<${kind}>`) as T;
3740
}
3841

0 commit comments

Comments
 (0)