Mask placeholder attributes when input masking is enabled - #1912
Mask placeholder attributes when input masking is enabled#1912carlosdanieltt wants to merge 1 commit into
Conversation
When maskAllInputs or maskInputOptions is enabled, only input values were masked while placeholder attributes were left in plain text. This could leak PII if apps set placeholder text dynamically with user data. Now placeholder attributes on input and textarea elements are masked through the same maskInputValue() path, respecting maskInputOptions granularity and custom maskInputFn callbacks. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
There was a problem hiding this comment.
Pull request overview
This PR extends rrweb’s input-masking behavior to also mask placeholder attributes on <input> and <textarea> elements, preventing potential PII leakage when placeholders contain user-derived text.
Changes:
- Mask
placeholderduring full snapshot serialization via the existingmaskInputValue()path. - Mask
placeholderattribute mutations in the recorder’sMutationBufferattribute handling. - Add/adjust integration test coverage and fixtures/snapshots to validate placeholder masking behavior under
maskAllInputs,maskInputOptions, andmaskInputFn.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/rrweb-snapshot/src/snapshot.ts | Masks placeholder values during element serialization using maskInputValue(). |
| packages/rrweb/src/record/mutation.ts | Extends attribute-mutation masking to include placeholder alongside value. |
| packages/rrweb/test/integration.test.ts | Adds an integration test asserting placeholders are masked when maskAllInputs is enabled. |
| packages/rrweb/test/html/form.html | Adds placeholder text to <input> and <textarea> fixtures used by integration tests. |
| packages/rrweb/test/snapshots/integration.test.ts.snap | Updates snapshots to include placeholder attributes and their masked/unmasked forms depending on configuration. |
Comments suppressed due to low confidence (1)
packages/rrweb/src/record/mutation.ts:588
- When masking
placeholder(andvalue) attribute mutations,maskInputValue()converts anullattribute value into an empty string. This meansremoveAttribute('placeholder')would be recorded asplaceholder: ""instead of removing the attribute, which can change replay semantics (attribute absence vs empty string). Preservenullby only masking when the attribute value is non-null.
if (attributeName === 'value' || attributeName === 'placeholder') {
const type = getInputType(target);
value = maskInputValue({
element: target,
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
maskAllInputsormaskInputOptionsis enabled, placeholder attributes on<input>and<textarea>elements are now masked through the samemaskInputValue()path as input valuesmaskInputOptionsgranularity (per input type) and custommaskInputFncallbacksTest plan
*characters whenmaskAllInputs: truemaskInputOptionstest confirms non-masked input types still show plain placeholdersmaskInputFntest confirms custom masking function applies to placeholders (textarea withdata-unmask-examplekeeps its placeholder unmasked)🤖 Generated with Claude Code