Session Replay: maskAttributes isn't applied to nodes added after the first snapshot; please move off @amplitude/rrweb-record 2.0.0-alpha.40

Open
#2,027 2 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 2 days

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
68/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
frontend, security

Research direction

Start with the MutationBuffer call in packages/rrweb/src/record/mutation.ts at the referenced lines, then run the provided jsdom reproduction with a node added after the first snapshot. Check the session replay package dependencies for the pinned @amplitude/rrweb-record, @amplitude/rrweb-types, and @amplitude/rrweb-plugin-console-record versions. Done means added-node title and aria-label values are masked and the alpha dependency or local patch is no longer required.

Written by the indexing model from the issue text.

Description

bug

Expected Behavior

With privacyConfig.maskAttributes: ["title", "aria-label"], Session Replay masks those attributes on every recorded node, including nodes added after the first full snapshot.

Current Behavior

Only the first full snapshot gets masked. When a DOM mutation adds a node later, rrweb records its attributes as raw values. In a single-page app that's every page after the first, so a name shown in title or aria-label lands in the replay in plain text. We found member names this way in our own replays.

For added nodes, MutationBuffer passes maskTextFn and maskInputFn to serializeNodeWithId but leaves out maskAttributeFn:

https://github.com/amplitude/rrweb/blob/eb8c0d54dd14d93e8e7680d654c637cfa8a65215/packages/rrweb/src/record/mutation.ts#L317-L331

@amplitude/rrweb-record 2.0.0-alpha.40, which @amplitude/[email protected] pins, has the gap. So does 2.1.4.

Possible Solution

  1. Add maskAttributeFn: this.maskAttributeFn to that serializeNodeWithId call. We ship this as a pnpm patch for now.
  2. Move @amplitude/session-replay-browser off the exact 2.0.0-alpha.40 pin and onto the stable 2.1.x line of @amplitude/rrweb-record, @amplitude/rrweb-types and @amplitude/rrweb-plugin-console-record, with the fix in. We'd rather not ship an alpha dependency or carry a patch.

Related: #2026. The plugin drops maskAttributes before it reaches the recorder.

Steps to Reproduce

import { record } from "@amplitude/rrweb-record";

const events: unknown[] = [];
record({
  emit: (event) => events.push(event),
  maskAttributeFn: (_key, value) => value.replace(/\S/g, "*"),
});

const row = document.createElement("button");
row.title = "Jane Member";
document.body.append(row);

// once the mutation event is emitted:
JSON.stringify(events).includes("Jane"); // true, expected false

Environment

  • JS SDK Version: @amplitude/analytics-browser 2.47.2, @amplitude/plugin-session-replay-browser 1.35.5, @amplitude/session-replay-browser 1.51.0, @amplitude/rrweb-record 2.0.0-alpha.40
  • Installation Method: pnpm
  • Browser and Version: Chrome; also reproduces in jsdom
Dominant language
TypeScript
Stars
181
Forks
66
Avg merge
2d 21h
Merged PRs (30d)
41

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from amplitude/Amplitude-TypeScript

All issues in amplitude/Amplitude-TypeScript

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.