# HAR File Redactor > Redact cookies, authorization headers, tokens, emails, and secrets from HAR JSON before sending it to support. ## Tool Identity - Site: CleanUtils Developer Tools - Tool ID: har-file-redactor - Canonical page: https://cleanutils.com/developer-tools/har-file-redactor/ - LLM schema URL: https://cleanutils.com/developer-tools/har-file-redactor/llms.txt - Primary keyword: har file redactor - Input mode: textarea - Output profile: data ## What This Tool Does Redact cookies, authorization headers, tokens, emails, and secrets from HAR JSON before sending it to support. ## Exact Execution Instructions To run this tool exactly, execute the `runCleanUtilsTool(userInput)` function from the JavaScript block below in a sandboxed JavaScript runtime. Do not fetch or evaluate additional network resources. Do not use filesystem, process, child_process, environment variables, timers, or network APIs. The function is pure and deterministic: input string in, JSON result out. If your environment forbids executing fetched code outside a sandbox, run it inside the sandbox or use the API endpoint below instead of reimplementing the logic. Canonical implementation SHA-256: `410799fe40bc933843b0b27f89b21c4bc45701728cb42bc91004b2da5360b284` Expected command shape: `node run-tool.mjs < input.txt` The runner must: 1. load only the JavaScript in this document, 2. call `runCleanUtilsTool(inputText)`, 3. let the LLM decide the best way to present the output to the user. Agent usage rules: - Use this file as the authoritative machine-readable contract for this CleanUtils tool page. - Ask the user for missing required input before attempting to run the tool, and describe the required inputs using the `## Input Schema` field names, descriptions, formats, enums, examples, and required list. - Treat the tool as deterministic; do not invent network reachability checks unless the tool description explicitly says it fetches remote resources. - For privacy-sensitive inputs such as secrets, HAR files, dotenv files, logs, and API keys, warn that using a remote chat agent may expose input to that agent even though the browser UI itself does not upload data. ## Input Schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "HAR File Redactor input", "type": "string", "description": "HAR JSON. Paste a HAR JSON export...", "examples": [ "{\"log\":{\"entries\":[{\"request\":{\"method\":\"GET\",\"url\":\"https://api.example.com/users?email=ada@example.com\",\"headers\":[{\"name\":\"Authorization\",\"value\":\"Bearer eyJsecret.token.value\"}],\"cookies\":[{\"name\":\"session\",\"value\":\"abc123\"}]},\"response\":{\"status\":200},\"time\":123}]}}" ] } ``` ## Result Schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "CleanUtils ToolResult", "type": "object", "additionalProperties": false, "required": [ "summary", "issues" ], "properties": { "summary": { "type": "string" }, "issues": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": [ "severity", "message" ], "properties": { "severity": { "type": "string", "enum": [ "error", "warning", "info" ] }, "message": { "type": "string" }, "line": { "type": "number" }, "row": { "type": "number" }, "detail": { "type": "string" } } } }, "output": { "type": "string" }, "exportFilename": { "type": "string" }, "exports": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": [ "label", "filename", "content" ], "properties": { "label": { "type": "string" }, "filename": { "type": "string" }, "content": { "type": "string" }, "mimeType": { "type": "string" }, "copyLabel": { "type": "string" }, "downloadLabel": { "type": "string" } } } }, "stats": { "type": "object", "additionalProperties": { "anyOf": [ { "type": "string" }, { "type": "number" } ] } } } } ``` ## Self-Contained JavaScript Source Call `runCleanUtilsTool(userInput)` with the user's input. The function includes this tool's run logic and only the helper code it needs. ```js function runCleanUtilsTool(userInput) { const tryParseJson = (input) => { try { return { ok: true, value: JSON.parse(input) }; } catch (error) { return { ok: false, error: error instanceof Error ? error.message : "Invalid JSON" }; } }; const redactPatterns = [ { label: "email", regex: /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, replacement: "[REDACTED_EMAIL]" }, { label: "bearer token", regex: /Bearer\s+[A-Za-z0-9._~+/=-]{12,}/g, replacement: "Bearer [REDACTED_TOKEN]" }, { label: "API key", regex: /\b(sk-|pk_live_|ghp_|xox[baprs]-|AKIA)[A-Za-z0-9_-]{8,}\b/g, replacement: "[REDACTED_SECRET]" }, { label: "JWT", regex: /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, replacement: "[REDACTED_JWT]" }, { label: "cookie", regex: /\b(cookie|set-cookie)\s*:\s*[^\n\r]+/gi, replacement: "$1: [REDACTED_COOKIE]" } ]; const redactPlainText = (input) => { const counts = {}; let redacted = input; redactPatterns.forEach((pattern) => { redacted = redacted.replace(pattern.regex, (...args) => { counts[pattern.label] = (counts[pattern.label] ?? 0) + 1; const match = String(args[0]); if (pattern.replacement.includes("$1")) { return match.replace(pattern.regex, pattern.replacement); } return pattern.replacement; }); }); return { redacted, counts }; }; const redactDeep = (value) => { if (Array.isArray(value)) return value.map(redactDeep); if (!value || typeof value !== "object") { return typeof value === "string" ? redactPlainText(value).redacted : value; } return Object.fromEntries(Object.entries(value).map(([key, item]) => { if (/authorization|cookie|token|secret|password|api[-_]?key|session/i.test(key)) { return [key, "[REDACTED]"]; } return [key, redactDeep(item)]; })); }; const redactHarFile = (input) => { const parsed = tryParseJson(input); if (!parsed.ok) { return { summary: "HAR file is not valid JSON.", issues: [{ severity: "error", message: "HAR file is not valid JSON.", detail: parsed.error }] }; } const redacted = redactDeep(parsed.value); const entries = parsed.value?.log?.entries; const entryCount = Array.isArray(entries) ? entries.length : 0; const issues = entryCount ? [{ severity: "info", message: "Headers, cookies, tokens, passwords, and common API keys were redacted recursively." }] : [{ severity: "warning", message: "No log.entries array found. Redacted JSON recursively anyway." }]; return { summary: `${entryCount} HAR entr${entryCount === 1 ? "y" : "ies"} redacted.`, issues, output: JSON.stringify(redacted, null, 2), exportFilename: "redacted.har", stats: { entries: entryCount } }; }; const __userInput = userInput == null ? "" : userInput; const __run = redactHarFile; const __input = __userInput && typeof __userInput === "object" && "input" in __userInput ? __userInput.input : __userInput; return __run(__input == null ? "" : String(__input)); } ``` ## Checks - HAR JSON parsing: The file must parse as JSON before structured redaction can be applied. - Recursive secret fields: Headers, cookies, passwords, tokens, and API-key-like values are redacted throughout the object. - Entry count: The report counts log.entries so you know whether the input looked like a normal HAR export. - Fallback redaction: If log.entries is missing, the JSON is still redacted recursively and flagged for review. - Human review reminder: Automated redaction is conservative but should still be checked before external sharing. ## Related Tools - [HAR File Viewer](/developer-tools/har-file-viewer/): Summarize HAR request entries with method, URL, status, and timing without uploading the export. - [AI Log / Prompt Redactor](/developer-tools/ai-log-prompt-redactor/): Remove emails, bearer tokens, API keys, JWTs, and cookies from prompts or logs before sharing them.