← Blog
Problem PrivHaven

How to remove personal data from a CSV before you share it

“I need to share a CSV export but it has customer emails and card numbers in it.”

Someone needs the data. A contractor, an analyst, a support agent, a vendor doing a migration. You export the table, open it, and there are email addresses in column D and what look like card numbers in column K.

You cannot send it as it is. You also cannot spend a day on it.

The short answer

Three steps, in order.

  1. Find every field that identifies a person, including the ones in free text columns.
  2. Replace those values in a way that keeps the file usable for whoever asked for it.
  3. Keep a record of what changed, so you can answer for it later.

If the data is covered by a contract or a policy that says it must not leave your machine, then step 2 has a fourth requirement. The tool has to do the work locally.

Why the quick approaches go wrong

Deleting the obvious columns. This catches the columns you thought of. Personal data has a habit of sitting in the ones you did not, particularly free text fields like notes, subject lines and shipping instructions.

Find and replace in a spreadsheet. Two problems. It only finds what you already know to look for, and spreadsheet applications reformat long digit strings on the way in. A 16 digit card number can arrive as scientific notation or lose its last digits before you have touched it.

A quick regular expression. This is the one that feels rigorous and is not. A pattern that matches 16 digits will flag every order number, tracking code and internal ID of that length. Tune it tighter and it starts missing real card numbers written with spaces or dashes. You end up reviewing hundreds of false hits by hand, which is the work you were trying to avoid.

Upload based scrubbing services. Many of these are good at the job. The catch is that the file has now gone to a machine you do not control, which was the constraint in the first place.

What to check in any tool you consider

  1. Does it validate, or only pattern match? Card numbers carry a check digit. IBANs carry a checksum. A tool that verifies those rejects the order numbers and keeps the real cards. A tool that only matches shapes cannot tell the difference, and the difference is most of the noise.

  2. Does the output stay usable? Whoever asked for the file usually still needs to join rows, spot duplicates or recognize a record. Replacing every value with REDACTED often breaks that. Keeping a stable fragment, like the last four digits, usually does not.

  3. Can you show what it did? If anyone ever asks which fields were removed from the file you sent, you want a record rather than a memory.

  4. Does the file leave your machine? You do not have to take anyone's word for this one, including ours. See below.

The check that belongs to no product

Open your browser's developer tools, go to the Network tab, and clear it. Then load your file into whatever browser based tool you are evaluating and run it.

Watch what happens. If your file is being processed somewhere else, a request has to carry it there, and you will see it. A tool that does the work locally will show you requests for its own code and nothing containing your data.

This works on any browser tool from any vendor. It is the only claim in this area that you can settle for yourself in about thirty seconds.

Free ways to do it

For a small file, doing it by hand is genuinely fine. Sort by each column, look at what is there, mask what needs masking. Under a few hundred rows this is faster than evaluating tools.

For a repeating job, a short script in whatever language you already use will handle the structured columns well. Write the checksum validation in, or you will be back to reviewing false hits. This costs nothing but your time, and it is the right answer if the shape of your exports rarely changes.

Where PrivHaven fits

PrivHaven is our CSV scrubber. It runs in the browser tab and the file does not leave your machine.

The specific things it does for this problem:

  • It detects Social Security numbers, credit card numbers, IBANs, ABA routing numbers, email addresses, phone numbers and dates of birth.
  • It validates rather than only matching. Card numbers are checked with the Luhn algorithm and IBANs with the mod 97 checksum, so an order number that happens to be 16 digits is not reported as a card. Findings are marked strong or medium, so you can see which ones rest on a checksum and which rest on formatting alone.
  • Masking keeps the last four characters, so a card reads as •••• 1234 and an SSN as •••-••-1234. Rows stay distinguishable.
  • It reads the file in chunks rather than all at once, so a large export does not have to fit in memory.
  • It produces a PDF report of what was found and what changed.

The engine is compiled to WebAssembly, a format browsers can run at close to native speed. That is the mechanism that makes local processing practical here, and it is why the network check above comes back empty. The engine has no network bindings compiled into it, so there is no code path that could send your file anywhere.

Cost. The free tier handles files up to 10,000 rows, and that ceiling is enforced inside the engine rather than in the page around it. Above that it is paid, per seat, with a three seat minimum on the team plan.

How it differs from the alternatives above. Against a script you wrote, it brings the checksum validation and the report without you maintaining them, and it costs money where the script does not. Against an upload based service, the file stays with you and you can verify that yourself, though a hosted service will usually offer integrations and scheduling that a browser tool does not.

If your exports are predictable and your script already works, keep the script. This is worth a look when the columns keep changing, when the free text fields are the problem, or when you need to show someone what was removed.