From 6c5fefc8467e370b4473de6f9fdc0c84fc693476 Mon Sep 17 00:00:00 2001 From: Frederico Luz Date: Thu, 12 Mar 2026 22:16:17 +0000 Subject: [PATCH] Security: redact sensitive values from command output Prevent secrets and sensitive data from leaking into stdout and model transcripts by redacting output from type, cookie, header, forms, and storage commands. Fixes #18 Co-Authored-By: Claude Opus 4.6 --- browse/src/read-commands.ts | 4 ++-- browse/src/write-commands.ts | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/browse/src/read-commands.ts b/browse/src/read-commands.ts index a473477..ccac915 100644 --- a/browse/src/read-commands.ts +++ b/browse/src/read-commands.ts @@ -65,7 +65,7 @@ export async function handleReadCommand( id: input.id || undefined, placeholder: input.placeholder || undefined, required: input.required || undefined, - value: input.value || undefined, + value: input.type === 'password' ? '[redacted]' : (input.value || undefined), options: el.tagName === 'SELECT' ? [...(el as HTMLSelectElement).options].map(o => ({ value: o.value, text: o.text })) : undefined, @@ -184,7 +184,7 @@ export async function handleReadCommand( const key = args[1]; const value = args[2] || ''; await page.evaluate(([k, v]) => localStorage.setItem(k, v), [key, value]); - return `Set localStorage["${key}"] = "${value}"`; + return `Set localStorage["${key}"]`; } const storage = await page.evaluate(() => ({ localStorage: { ...localStorage }, diff --git a/browse/src/write-commands.ts b/browse/src/write-commands.ts index e1c9194..d222d38 100644 --- a/browse/src/write-commands.ts +++ b/browse/src/write-commands.ts @@ -94,7 +94,7 @@ export async function handleWriteCommand( const text = args.join(' '); if (!text) throw new Error('Usage: browse type '); await page.keyboard.type(text); - return `Typed "${text}"`; + return `Typed ${text.length} characters`; } case 'press': { @@ -153,7 +153,7 @@ export async function handleWriteCommand( domain: url.hostname, path: '/', }]); - return `Cookie set: ${name}=${value}`; + return `Cookie set: ${name}=****`; } case 'header': { @@ -163,7 +163,9 @@ export async function handleWriteCommand( const name = headerStr.slice(0, sep).trim(); const value = headerStr.slice(sep + 1).trim(); await bm.setExtraHeader(name, value); - return `Header set: ${name}: ${value}`; + const sensitiveHeaders = ['authorization', 'cookie', 'set-cookie', 'x-api-key', 'x-auth-token']; + const redactedValue = sensitiveHeaders.includes(name.toLowerCase()) ? '****' : value; + return `Header set: ${name}: ${redactedValue}`; } case 'useragent': {