Where Does Session Replay Cross the Line?

Image Source: depositphotos.com

Session replay has quietly become default infrastructure. Product teams want to see where users stall, support wants to stop asking "can you send a screenshot," and engineering wants a reproduction path for the bug that only happens on one customer's machine. The business case writes itself. The security review, in most organisations, never really happened.

So when the question finally comes up — where does this stop being lawful? — most teams go looking for the answer in the wrong place.

Two courts, two answers

Session replay has drawn a steady stream of US class actions over the last several years, brought under state wiretapping statutes. California's Invasion of Privacy Act and Pennsylvania's Wiretapping and Electronic Surveillance Control Act do most of the work. The theory is straightforward: the replay script is a third party listening in on a conversation between the user and the website, and nobody asked the user.

For a while, defendants could reasonably assume most of these claims would die early — that a plaintiff who could not point to any concrete harm would not get through the door. The federal appellate courts have since split on exactly that point.

The Ninth Circuit has repeatedly held that the presence of session replay code, on its own, does not establish a reasonable expectation of privacy sufficient to give a plaintiff standing. Record the browsing, and without more, there is no case.

The Third Circuit went the other way, drawing a distinction rather than applying a blanket rule. In its leading decision on the question, eight plaintiffs sued over the same replay deployment. Six of them — whose ordinary browsing had been captured — were dismissed. Two were not. The difference between those two groups was that the recordings of the second group contained their payment card details.

Six lost. Two, whose financial data ended up in the recording, did not.

The courts were never really the variable

It is tempting to read that split as a jurisdictional problem: keep an eye on which circuit you can be sued in, watch for the Supreme Court to resolve it, brief your counsel.

That reading misses what actually happened. Strip out the procedural machinery, and both courts are looking at the same thing — what the recording contained. One court says browsing data alone is not enough. The other agrees, and adds that payment data is. They are not applying different principles to the same facts. They are applying a similar principle to different payloads, and reaching the answers the payloads dictate.

Which means the variable was never the court. It was the recording.

And a recording is not a legal artefact. It is an engineering output — the direct, predictable result of masking rules, route exclusions and retention settings that a developer configured, months before anyone filed anything. Two companies running the identical tool in the identical jurisdiction can land on opposite sides of that line, entirely because of what one of them chose not to capture.

The line is real. It just isn't drawn where people look for it.

Which is why the checkout is the whole problem

If sensitivity is what decides, then the risk is not spread evenly across your product. It is concentrated almost entirely in one flow.

Card data also carries its own rules, and they are blunt: the security code on the back of a card is never supposed to be retained after a payment is authorised — not by the merchant, not by anyone, under any circumstances. Card numbers themselves can be kept only under a specific set of protections.

A session recording that captured either one is retention. It is retention in a system nobody included in scope, on infrastructure nobody assessed, held for however long the replay tool's default happens to be. Nobody decided to do that. It happened because nobody decided not to.

"We use hosted fields, so we're fine"

This is the answer most teams give, and it is right often enough to be dangerous. Payment fields served by a provider inside a cross-origin iframe genuinely are out of the recorder's reach — the browser's same-origin policy handles it, and that is the intended behaviour.

The trouble is that the checkout is more than those fields. Four paths get payment data into recordings anyway.

Mixed forms and fallbacks. A checkout that combines hosted fields with your own inputs — cardholder name, billing address, sometimes a postcode for address verification — is recording everything except the iframe. Some integrations also fall back to a non-hosted variant when a browser blocks third-party frames or a script fails to load. That fallback is rarely the path anyone tests with the recorder switched on.

The confirmation page. Nothing here was typed, so masking rules aimed at input fields never touch it. The order summary, the last four digits, the billing and delivery address, the customer's full name — all rendered onto the page, all faithfully recorded. This is the most common way payment data ends up in a replay archive, and it is almost never on anyone's list.

Autofill. Browsers and password managers fill fields programmatically. Depending on how the recorder watches for changes, values that arrive without keystrokes can behave differently from typed input — under masking rules that were only ever tested by hand.

Failed payments. The path security teams miss most often, because it lives in a different part of the stack. Where replay ships alongside error tracking, a declined transaction frequently throws an exception carrying the application's state — the request body, the form object, sometimes the token. Nobody checked that against the masking policy, because nobody thought of it as a recording.

Draw the line around the flow, not the field

Field-level masking is the right tool across the rest of the product. In the payment flow, it is the wrong unit of control, because it asks you to enumerate correctly — forever, across every release, every A/B variant, every fallback path. One new field ships unclassified, and the guarantee is gone, silently, with no error and no alert.

The stronger posture is to stop recording the checkout altogether: suppress capture from the moment the user enters the payment step until the confirmation page is behind them. You lose replay coverage on the flow you would most like to debug. You gain a control you can state in one sentence, one that does not depend on a selector list staying accurate through the next redesign.

For teams unwilling to go dark at checkout — and there are good reasons not to — the middle path is to record structure without content: events, timings, navigation and errors, with all text and all input values suppressed by default inside that flow. You keep the funnel diagnostics. You do not keep the data.

What to ask before you deploy

Whichever platform you are running — LogNroll, or any of the other session replay and error tracking tools on the market — these are the questions that decide where your line actually falls, and they are worth putting to the vendor in writing.

Where does the redaction happen? If masking runs server-side, the raw data existed on the wire and in an ingest queue before anything was removed. "We discard it on arrival" is a materially weaker answer than "it never left the browser."

Can capture be switched off for a whole route, not just an element? If the only granularity on offer is the CSS selector, you cannot implement the control above.

What is kept by default, and for how long? Replay data is heavy, and its investigative value decays fast. Thirty days covers nearly every legitimate debugging need. Indefinite retention turns a debugging tool into a breach-impact multiplier.

Does error tracking use the same masking policy? If replay and errors are separate subsystems with separate configuration, assume they are, and check.

Where is it stored, and who can reach it? The recording archive stores customer data and inherits every obligation that comes with it. If the answer involves a region or a subprocessor nobody has assessed, that is a procurement question, not a settings question.

Then test it, because a masking policy is a control

Seed a staging environment with values you will recognise: a test card number, a distinctive string in every free-text field, a made-up postcode. Run a full purchase, including a deliberately declined one. Then search the stored recordings — and the stored error payloads — for those strings.

Anything that comes back is a finding. Re-run it after every significant frontend release, because masking rules bound to CSS selectors break silently when the markup changes, and nothing in the pipeline will tell you they did.

The reasonable position

None of this is an argument against session replay. Reproducing a defect from a real recording instead of three rounds of email is a genuine engineering and support win, and teams that give it up generally ship slower and guess more.

The argument is narrower. Session replay is a data collection pipeline pointed at your users' screens, and at checkout it is pointed at the most sensitive data your product ever handles.

So where does it cross the line? Not in a courtroom in California or Pennsylvania. In the masking policy, in the route exclusion somebody wrote or didn't. That is the uncomfortable version — and also the good one, because the recording is the one part of this you fully control.

Decide what goes into it before somebody else decides what it means.