From 127a4e512bd468597d6af954f262d899d1b0d822 Mon Sep 17 00:00:00 2001 From: 0xbyt4 <35742124+0xbyt4@users.noreply.github.com> Date: Wed, 1 Apr 2026 02:08:58 +0300 Subject: [PATCH] security: redact secrets from auxiliary and vision LLM responses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LLM responses from browser snapshot extraction and vision analysis could echo back secrets that appeared on screen or in page content. Input redaction alone is insufficient — the LLM may reproduce secrets it read from screenshots (which cannot be text-redacted). Now redact outputs from: - _extract_relevant_content (auxiliary LLM response) - browser_vision (vision LLM response) - camofox_vision (vision LLM response) --- tools/browser_camofox.py | 6 +++++- tools/browser_tool.py | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/browser_camofox.py b/tools/browser_camofox.py index b8f332dd66..c2278f83ef 100644 --- a/tools/browser_camofox.py +++ b/tools/browser_camofox.py @@ -522,7 +522,11 @@ def camofox_vision(question: str, annotate: bool = False, task="vision", timeout=_vision_timeout, ) - analysis = response.choices[0].message.content if response.choices else "" + analysis = (response.choices[0].message.content or "").strip() if response.choices else "" + + # Redact secrets the vision LLM may have read from the screenshot. + from agent.redact import redact_sensitive_text + analysis = redact_sensitive_text(analysis) return json.dumps({ "success": True, diff --git a/tools/browser_tool.py b/tools/browser_tool.py index 7523d5db57..04e869b0ff 100644 --- a/tools/browser_tool.py +++ b/tools/browser_tool.py @@ -1048,7 +1048,9 @@ def _extract_relevant_content( if model: call_kwargs["model"] = model response = call_llm(**call_kwargs) - return (response.choices[0].message.content or "").strip() or _truncate_snapshot(snapshot_text) + extracted = (response.choices[0].message.content or "").strip() or _truncate_snapshot(snapshot_text) + # Redact any secrets the auxiliary LLM may have echoed back. + return redact_sensitive_text(extracted) except Exception: return _truncate_snapshot(snapshot_text) @@ -1740,6 +1742,9 @@ def browser_vision(question: str, annotate: bool = False, task_id: Optional[str] response = call_llm(**call_kwargs) analysis = (response.choices[0].message.content or "").strip() + # Redact secrets the vision LLM may have read from the screenshot. + from agent.redact import redact_sensitive_text + analysis = redact_sensitive_text(analysis) response_data = { "success": True, "analysis": analysis or "Vision analysis returned no content.",