Skip to content

Commit 2af4009

Browse files
mydeabillyvg
authored andcommitted
feat: Enforce masking of credit card fields (#166)
This is on top of #165, actually fixing the behavior so that certain fields cannot be unmasked. This is a pretty straightforward fix, a bit "hacky" but should work well enough. Fixes getsentry/sentry-javascript#10258 --------- Co-authored-by: mydea <[email protected]>
1 parent 28546ea commit 2af4009

File tree

5 files changed

+758
-14
lines changed

5 files changed

+758
-14
lines changed

packages/rrweb-snapshot/src/snapshot.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,24 @@ export function needMaskingText(
384384
: node.parentElement;
385385
if (el === null) return false;
386386

387+
if (el.tagName === 'INPUT') {
388+
// Special cases: We want to enforce some masking for password & credit-card related fields,
389+
// no matter the settings
390+
const autocomplete = el.getAttribute('autocomplete');
391+
const disallowedAutocompleteValues = [
392+
'current-password',
393+
'new-password',
394+
'cc-number',
395+
'cc-exp',
396+
'cc-exp-month',
397+
'cc-exp-year',
398+
'cc-csc',
399+
];
400+
if (disallowedAutocompleteValues.includes(autocomplete as string)) {
401+
return true;
402+
}
403+
}
404+
387405
let maskDistance = -1;
388406
let unmaskDistance = -1;
389407

packages/rrweb-snapshot/test/__snapshots__/integration.test.ts.snap

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -277,25 +277,25 @@ exports[`integration tests [html file]: form-fields-sensitive.html 1`] = `
277277
<input type=\\"password\\" value=\\"*******\\" />
278278
</label>
279279
<label>
280-
<input autocomplete=\\"current-password\\" value=\\"initial\\" />
280+
<input autocomplete=\\"current-password\\" value=\\"*******\\" />
281281
</label>
282282
<label>
283-
<input autocomplete=\\"new-password\\" value=\\"initial\\" />
283+
<input autocomplete=\\"new-password\\" value=\\"*******\\" />
284284
</label>
285285
<label>
286-
<input autocomplete=\\"cc-number\\" value=\\"initial\\" />
286+
<input autocomplete=\\"cc-number\\" value=\\"*******\\" />
287287
</label>
288288
<label>
289-
<input autocomplete=\\"cc-exp\\" value=\\"initial\\" />
289+
<input autocomplete=\\"cc-exp\\" value=\\"*******\\" />
290290
</label>
291291
<label>
292-
<input autocomplete=\\"cc-exp-month\\" value=\\"initial\\" />
292+
<input autocomplete=\\"cc-exp-month\\" value=\\"*******\\" />
293293
</label>
294294
<label>
295-
<input autocomplete=\\"cc-exp-year\\" value=\\"initial\\" />
295+
<input autocomplete=\\"cc-exp-year\\" value=\\"*******\\" />
296296
</label>
297297
<label>
298-
<input autocomplete=\\"cc-csc\\" value=\\"initial\\" />
298+
<input autocomplete=\\"cc-csc\\" value=\\"*******\\" />
299299
</label>
300300
</form>
301301
</body></html>"
@@ -313,25 +313,25 @@ exports[`integration tests [html file]: form-fields-sensitive-update.html 1`] =
313313
<input type=\\"password\\" value=\\"*********\\" />
314314
</label>
315315
<label>
316-
<input autocomplete=\\"current-password\\" value=\\"new value\\" />
316+
<input autocomplete=\\"current-password\\" value=\\"*********\\" />
317317
</label>
318318
<label>
319-
<input autocomplete=\\"new-password\\" value=\\"new value\\" />
319+
<input autocomplete=\\"new-password\\" value=\\"*********\\" />
320320
</label>
321321
<label>
322-
<input autocomplete=\\"cc-number\\" value=\\"new value\\" />
322+
<input autocomplete=\\"cc-number\\" value=\\"*********\\" />
323323
</label>
324324
<label>
325-
<input autocomplete=\\"cc-exp\\" value=\\"new value\\" />
325+
<input autocomplete=\\"cc-exp\\" value=\\"*********\\" />
326326
</label>
327327
<label>
328-
<input autocomplete=\\"cc-exp-month\\" value=\\"new value\\" />
328+
<input autocomplete=\\"cc-exp-month\\" value=\\"*********\\" />
329329
</label>
330330
<label>
331-
<input autocomplete=\\"cc-exp-year\\" value=\\"new value\\" />
331+
<input autocomplete=\\"cc-exp-year\\" value=\\"*********\\" />
332332
</label>
333333
<label>
334-
<input autocomplete=\\"cc-csc\\" value=\\"new value\\" />
334+
<input autocomplete=\\"cc-csc\\" value=\\"*********\\" />
335335
</label>
336336
</form>
337337

packages/rrweb-snapshot/test/snapshot.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,34 @@ describe('needMaskingText', () => {
497497
),
498498
).toEqual(false);
499499
});
500+
501+
describe('enforced masking', () => {
502+
it.each([
503+
'current-password',
504+
'new-password',
505+
'cc-number',
506+
'cc-exp',
507+
'cc-exp-month',
508+
'cc-exp-year',
509+
'cc-csc',
510+
])('enforces masking for autocomplete="%s"', (autocompleteValue) => {
511+
document.write(
512+
`<input autocomplete='${autocompleteValue}' value='initial' class='unmaskmask'></input>`,
513+
);
514+
const el = document.querySelector('input')!;
515+
expect(
516+
needMaskingText(el, 'maskmask', '.foo', 'unmaskmask', null, false),
517+
).toEqual(true);
518+
});
519+
520+
it('does not mask other autocomplete values', () => {
521+
document.write(
522+
`<input autocomplete='name' value='initial' class='unmaskmask'></input>`,
523+
);
524+
const el = document.querySelector('input')!;
525+
expect(
526+
needMaskingText(el, 'maskmask', '.foo', 'unmaskmask', null, false),
527+
).toEqual(false);
528+
});
529+
});
500530
});

0 commit comments

Comments
 (0)