# HAR File Sanitizer

How the HAR File Sanitizer replaces credentials, cookies, keys and personal values in a HAR file with stable placeholders in the browser, what it detects and what it does not, and how to prepare a HAR file for a support ticket.

Canonical: https://docs.tamperbox.dev/tools/har-sanitizer/
Updated: 2026-10-26
Applies to: tamperbox.dev, October 2026
Prerequisites: A HAR file exported from a browser's developer tools (Network panel, Save all as HAR or Export HAR), up to 50 MiB
Outputs: A verdict, every replacement by request and place, the sanitized HAR to copy or download, and the request list with failures as a Markdown table
Limitations: Detection is by field name and known patterns; names, postal addresses and phone numbers in free text are not detected; binary bodies are not inspected; nothing is sent anywhere

The tool page is [tamperbox.dev/har-sanitizer](https://tamperbox.dev/har-sanitizer). It opens on a sample capture from a shop on the reserved `.example` domain: a sign-in that returns a token, an order list called with that token and a session cookie, and a checkout that fails with a card number in its body.

<div class="tb-callout"><strong>Where processing happens:</strong> the HAR file is read and cleaned in your browser and never uploaded, including files you open or drop. No server request is made.</div>

## What the tool answers

Can I attach this HAR file to a ticket? A HAR file records every request and response the browser made, with headers, cookies and bodies. Session cookies and bearer tokens in it let anyone holding the file act as the user until they expire. The tool replaces what it can find, tells you exactly what and where, and lists the requests so you can point support at the ones that failed.

## Inputs

### Pasted text

Paste the HAR JSON into the box. Text over one million characters is kept out of the box so the page stays responsive; the box says what is loaded.

### Files

Drop a `.har` or `.json` file anywhere on the page, or use Open file. Files up to 50 MiB are read in the browser.

### Options

- **Every cookie value:** on by default. Cookie names stay, so you can see which cookies were sent.
- **Email addresses** and **Card numbers:** on by default.
- **IP addresses:** off by default, because they are usually needed to diagnose network problems.
- **JSON Web Tokens:** keep claims and remove the signature (default), or replace the whole token.
- **More field names to replace:** names your application uses for private values, such as `tenant` or `account_id`.

## Reading the result

### Verdict and chips

How many distinct values were replaced, in how many requests, with a chip per kind, a chip for failed requests and a chip for binary bodies that were not inspected.

### What was replaced

One row per place: the request number, the placeholder and where it was (`request header authorization`, `response body > access_token`, `request query`). Original values are never shown.

### Sanitized HAR

The cleaned file, with Copy and Download. The download is named after your file with `.sanitized.har`.

### Requests

Every request with method, status, sanitized URL and time. Failed means status 0 (blocked, cancelled or a network error) or 400 and above. Copy failures as Markdown gives a table ready for a ticket.

## Method

### 1. Reading

The text is parsed as JSON and must hold `log.entries` as a list. A leading byte order mark is ignored.

### 2. By name

Names are compared after lowercasing and removing everything but letters and digits. A name is a credential when it contains authorization, token, secret, password, passphrase, apikey, session, csrf, xsrf, signature, credential, privatekey, codeverifier, samlresponse, samlrequest, otp or cookie, or is exactly key, sig, sid, auth, pass, pwd, pin, ssn, cvv or cvc. `code` counts only in a URL query or form, where it is an OAuth authorization code. Names that end in type, expires, expiry, endpoint, url, uri, hint, length or format are treated as descriptive metadata, except names containing password, passwd or secret, which are always redacted.

This applies to headers, query parameters, form fields, `postData.params` and keys at any depth of a JSON body.

### 3. Headers and cookies

Authorization and Proxy-Authorization keep their scheme. Cookie and Set-Cookie keep each name and attribute and lose the value. The `cookies` lists of requests and responses are treated the same way. Location, Referer, Origin and Content-Location are cleaned as URLs.

### 4. URLs

User and password in a URL are replaced, query parameters and OAuth or SPA fragment parameters are cleaned by name, including repeated parameters and malformed percent escapes, and the whole URL is searched for the patterns below.

### 5. Patterns in any text

Supported header, query, body, comment and custom metadata text is searched for: private key blocks; AWS access key IDs; Google API keys; GitHub tokens; Stripe secret and restricted keys; Slack tokens; JSON Web Tokens; credentials after Bearer, Basic or Token; email addresses; 13 to 19 digit numbers that pass the Luhn check; and, when chosen, IPv4 addresses outside the documentation and loopback ranges.

### 6. Placeholders

Each distinct value gets one placeholder for the whole file: `[TOKEN_n]`, `[PASSWORD_n]`, `[COOKIE_n]`, `[CARD_n]`, a named key such as `[AWS_KEY_n]`, `email-n@redacted.invalid`, and for IP addresses a documentation address from the three documentation ranges (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24), followed by `[IP_n]` after 762 distinct addresses. A JSON Web Token keeps its header, has its claims cleaned the same way (so an email claim is replaced), and gets `redacted-signature` as its signature. Input that looks like a placeholder is still untrusted. Running the tool again may renumber placeholders; the mapping is stable within each run.

### 7. Bodies

JSON bodies are parsed, cleaned and written with the indentation they had. URL-encoded and multipart form bodies are cleaned field by field. Sensitive JSON names also apply to values inside arrays and nested objects. Malformed JSON or multipart bodies are replaced as a whole, rather than retained without inspection. Data deeper than 100 levels is refused. Other text is searched for patterns. Base64 bodies with a text, JSON, XML, JavaScript or form type are decoded, cleaned and encoded again; other Base64 bodies are binary and are kept and counted.

## Standards and conformance

### Format recognition has a limited scope

The commonly cited [HAR format document](https://w3c.github.io/web-performance/specs/HAR/Overview.html#sec-log) is an abandoned historical draft, not a current W3C Recommendation. It remains useful for interpreting the familiar `log`, `entries`, request, response and content objects emitted by browser tools. This sanitizer checks the structure it needs to traverse safely; it is not a comprehensive HAR conformance validator.

The implemented parser checks for a log object, an entries array, object entries and suitable shapes for supplied request, response and header/cookie/query lists. It rejects data nested beyond 100 levels. Successful parsing does not establish that timing totals, encoded body sizes, HTTP versions or browser-specific metadata are internally consistent. Preserve the original capture when investigating capture-tool defects.

### Redaction and protocol meaning

HTTP status interpretation follows the status-code families in [RFC 9110 section 15](https://www.rfc-editor.org/rfc/rfc9110#section-15). The additional status-zero bucket is a capture convention used for incomplete or failed requests, not an HTTP response status assigned by that RFC. A failure row identifies a diagnostic candidate; it does not determine whether the cause was cancellation, a browser policy, the network or the application.

[JWT claims](https://www.rfc-editor.org/rfc/rfc7519#section-4) can carry sensitive application data beyond recognizable email addresses or credential-like field names. Removing a signature changes the token, but retained claims still require review. Prefer whole-token replacement when claims are unnecessary. The sanitizer does not contact an issuer, revoke credentials or test whether a server correctly rejects modified tokens.

## Finding reference

| Finding | Severity | Source | What it means | Fix |
| --- | --- | --- | --- | --- |
| N values replaced | pass | [W3C HAR](https://w3c.github.io/web-performance/specs/HAR/Overview.html) | Credentials and personal values were found and replaced | Read the file before sharing |
| Nothing to replace found | info | | No credential names or known patterns matched | Read the file anyway; only recognized patterns in free text are detected |
| N failed requests | check | [RFC 9110 15](https://www.rfc-editor.org/rfc/rfc9110#section-15) | Status 0 or 400 and above | Copy failures as Markdown for the ticket |
| Binary bodies not inspected | info | | Images, fonts and archives were kept as they are | Remove the entries if a binary could hold private data |
| Not a HAR file | fail | [W3C HAR](https://w3c.github.io/web-performance/specs/HAR/Overview.html) | No `log.entries` list | Export again from the Network panel; Heal it can wrap a bare `entries` list |

## Guide

### Prepare a HAR file for a support ticket

1. Record: open the developer tools, Network panel, tick Preserve log, reproduce the problem, then Save all as HAR (Chrome, Edge) or Export HAR (Firefox, Safari).
2. Drop the file here. Read What was replaced, and add your own field names under More field names if something private was missed.
3. Download the sanitized file and attach it. Paste Copy failures as Markdown into the ticket.
4. Sign out of the session you recorded, so the original cookies stop working even if the original file leaks.

### Share tokens without making them usable

Keep the default JWT setting. Support can read retained claims, while the original signature is replaced. Review the claims too; this does not verify server rejection or revoke the original credential.

### Break it cases

| Case | What it adds | What it shows |
| --- | --- | --- |
| Token in a URL | A request with `access_token` in the query | A credential replaced in the URL |
| API key header | A request with an X-API-Key header | A credential replaced in a header |
| Card in a body | A JSON body with a card number | A card number replaced |
| Private key in a response | A text response holding a private key block | A private key replaced |
| Blocked request | A request with status 0 | A failed request in the list |
| Not a HAR file | A bare `entries` object | The error and the Heal it repair |

## Worked example

### Review the three-request opening capture

The reserved-domain example contains sign-in, order retrieval and checkout. Follow the same email or credential across its occurrences: stable placeholders within a run retain useful relationships while removing the original recognized value. A placeholder count and an occurrence count answer different questions. One credential can appear in several requests and therefore produce several report locations.

Inspect the failed checkout separately from the redaction list. Its failure status is useful to the support investigation even after the card-like value is replaced. Copying failures as Markdown should preserve request order and the sanitized URL. Then inspect the exported HAR itself: the table is a summary, not the complete artifact that another person will receive.

### Account for fields the detector cannot understand

Add an application-specific field name when its value must be removed regardless of its shape. An opaque customer identifier does not have to resemble an email address or standard token. Consider whether retaining it is necessary to explain the failure, and verify every occurrence in the output rather than assuming that one redacted JSON field covers a URL path or an unrelated free-text message.

Names, addresses and arbitrary personal prose can remain. Binary attachments can also contain information that the text matcher never reads. When a request is irrelevant to the investigation, omitting that request can be more appropriate than expecting generic redaction to interpret its contents. The tool's report is evidence of performed substitutions, not a certificate that the artifact contains no private data.

## Use it from an agent

The `har_sanitize` operation takes the HAR JSON and returns the sanitized HAR, with a warning that counts the replacements by kind. Options match the page: `cookies`, `emails`, `cards`, `ips` and `jwt`. Through the API the input goes to our server and is limited to the API's request size; use the page for files you do not want to send anywhere. See the [MCP documentation](https://docs.tamperbox.dev/mcp/).

## Limits

- Names, postal addresses, phone numbers and other personal details in free text are not detected.
- Binary bodies are not inspected.
- Changed bodies are written out again, so Content-Length headers may not match.
- Files are limited to 50 MiB in the browser.


## Verification before sharing

### Check the exported artifact independently

Open the downloaded sanitized file as data and search for known sample secrets from the original, including URL-encoded representations where relevant. Confirm that the requests needed for reproduction remain understandable and that the selected cookie and JWT options match the intended disclosure. Never use the presence of many replacements as the sole reason to stop reviewing.

A second sanitizer run is not an equivalence or completeness test. Placeholder numbering is scoped to a run and placeholder-looking input is still treated as untrusted data. Compare the intended semantics of requests, not byte-for-byte equality between repeated runs. Preserve timing and error information needed by the recipient while removing details they do not need.

### Keep redaction separate from replay

A sanitized capture is intended for inspection. Replaced passwords, modified tokens and rewritten bodies can make replay fail, and length-related metadata may no longer describe the new body. Do not treat a replay failure as evidence that the original recorded request failed in the same way. Conversely, do not test a retained credential against a live service merely to check whether redaction was necessary.

When generating mocks from a sanitized HAR, review the mock output and choose deliberate test values for removed fields. Use [HAR to Mocks](https://tamperbox.dev/har-to-mocks) for supported response fixtures, keeping its matching limits separate from this sanitizer's detection limits. A useful support artifact and an executable test fixture have different acceptance criteria.

## References

- [W3C: HTTP Archive (HAR) format](https://w3c.github.io/web-performance/specs/HAR/Overview.html)
- [RFC 7519: JSON Web Token](https://www.rfc-editor.org/rfc/rfc7519)
- [RFC 6265: HTTP State Management Mechanism](https://www.rfc-editor.org/rfc/rfc6265)
- [OWASP: Logging Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html)
