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 <noreply@anthropic.com>
This commit is contained in:
Frederico Luz 2026-03-12 22:16:17 +00:00
parent 1b317aae9a
commit 6c5fefc846
2 changed files with 7 additions and 5 deletions

View File

@ -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 },

View File

@ -94,7 +94,7 @@ export async function handleWriteCommand(
const text = args.join(' ');
if (!text) throw new Error('Usage: browse type <text>');
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': {