From 041e11b8ca681be94c08e22575b1d6b26d7cf06b Mon Sep 17 00:00:00 2001 From: Yi LIU Date: Mon, 16 Feb 2026 15:41:38 +0800 Subject: [PATCH] fix: redact sensitive headers in network request output Network request details expose all HTTP headers in plain text, including sensitive values like Authorization tokens, Cookie values, and API keys. This data gets passed to the MCP client (typically an LLM) where it could be logged or inadvertently included in responses. Redact known sensitive headers (Authorization, Cookie, Set-Cookie, Proxy-Authorization) in both the text and structured JSON output of network request details. --- src/formatters/NetworkFormatter.ts | 33 +++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/formatters/NetworkFormatter.ts b/src/formatters/NetworkFormatter.ts index 313e091cb..09acfb3e5 100644 --- a/src/formatters/NetworkFormatter.ts +++ b/src/formatters/NetworkFormatter.ts @@ -10,6 +10,13 @@ import type {HTTPRequest, HTTPResponse} from '../third_party/index.js'; const BODY_CONTEXT_SIZE_LIMIT = 10000; +const SENSITIVE_HEADERS = new Set([ + 'authorization', + 'cookie', + 'set-cookie', + 'proxy-authorization', +]); + export interface NetworkFormatterOptions { requestId?: number | string; selectedInDevToolsUI?: boolean; @@ -204,10 +211,12 @@ export class NetworkFormatter { return { ...this.toJSON(), - requestHeaders: this.#request.headers(), + requestHeaders: NetworkFormatter.#redactHeaders(this.#request.headers()), requestBody: this.#requestBody, requestBodyFilePath: this.#requestBodyFilePath, - responseHeaders: this.#request.response()?.headers(), + responseHeaders: NetworkFormatter.#redactHeaders( + this.#request.response()?.headers(), + ), responseBody: this.#responseBody, responseBodyFilePath: this.#responseBodyFilePath, failure: this.#request.failure()?.errorText, @@ -217,6 +226,21 @@ export class NetworkFormatter { }; } + static #redactHeaders( + headers?: Record, + ): Record | undefined { + if (!headers) { + return undefined; + } + const redacted: Record = {}; + for (const [name, value] of Object.entries(headers)) { + redacted[name] = SENSITIVE_HEADERS.has(name.toLowerCase()) + ? '' + : value; + } + return redacted; + } + #getStatusFromRequest(request: HTTPRequest): string { const httpResponse = request.response(); const failure = request.failure(); @@ -238,7 +262,10 @@ export class NetworkFormatter { #getFormattedHeaderValue(headers: Record): string[] { const response: string[] = []; for (const [name, value] of Object.entries(headers)) { - response.push(`- ${name}:${value}`); + const displayValue = SENSITIVE_HEADERS.has(name.toLowerCase()) + ? '' + : value; + response.push(`- ${name}:${displayValue}`); } return response; }