主题
认证与安全
本文引用的源码文件
本文引用的文件
- agent/src/auth.js
- agent/src/security.js
- agent/src/server.js
- src/shared/secret.js
- agent/src/crypto-lite.js
- src/storage/token-store.js
- src/background/token-recorder.js
- src/options/config-manager.js
- src/options/toolbox-shared.js
- src/side_panel/workspace-manager.js
- src/side_panel/index.js
- src/side_panel/chat-manager.js
- src/background/index.js
- src/background/react-loop.js
- src/options/config-io.js
更新摘要
变更内容
- 修复了侧边栏图片API密钥处理的安全漏洞,确保加密凭证被正确解密为明文密钥
- 在side_panel/index.js中添加了统一的decodeSecret()解密逻辑,用于处理incoming key changes
- 完善了图片识别API密钥在整个应用生命周期中的数据完整性保护
- 更新了相关流程图和故障排查指南以反映新的安全机制
目录
引言
本文件面向"认证与安全"子系统,覆盖以下目标:
- Token 验证机制:配对码流程、临时会话建立、设备绑定与令牌校验。
- 权限控制系统:路径沙箱、命令分级管控、黑名单/灰名单策略与强制模式。
- 审计与统计:Token 使用记录、全局与会话级汇总、按模型与调用类型聚合。
- 加密工具函数:密钥/Token 落盘混淆(Base64 + 前缀标记)、兼容旧明文。
- 安全配置建议:TLS、CORS、速率限制与安全头(本节为通用实践建议,不直接分析具体源码)。
本项目采用双进程架构:Chrome 扩展端(Manifest V3)与独立本地代理端 Agent(Node.js)。两端通过 HTTP/WebSocket 通信;Agent 侧负责配对认证、路径与命令安全控制、以及持久化统计。
重要安全更新:最近修复了侧边栏图片API密钥处理的安全漏洞,确保所有模块在处理图片识别API密钥时都正确解密存储的加密密钥,防止将密文发送给视觉模型API导致鉴权失败。
项目结构
与安全相关的关键代码分布如下:
- 代理端认证模块:agent/src/auth.js
- 代理端安全网关:agent/src/security.js
- 代理端 HTTP 入口与路由集成:agent/src/server.js
- 共享密钥混淆(扩展端):src/shared/secret.js
- 代理端密钥混淆(Node 端):agent/src/crypto-lite.js
- 扩展端 Token 统计存储:src/storage/token-store.js
- 扩展端 Token 统计采集:src/background/token-recorder.js
- 配置管理(含令牌解码):src/options/config-manager.js
- 工具箱共享状态(含令牌解码):src/options/toolbox-shared.js
- 工作区管理器(含令牌解码):src/side_panel/workspace-manager.js
- 新增:侧边栏图片API密钥处理:src/side_panel/index.js, src/side_panel/chat-manager.js
- 新增:背景脚本图片API密钥传递:src/background/index.js, src/background/react-loop.js
graph TB subgraph "扩展端" BR["background/token-recorder.js"] TS["storage/token-store.js"] SS["shared/secret.js"] CM["options/config-manager.js"] TB["options/toolbox-shared.js"] WM["side_panel/workspace-manager.js"] SP["side_panel/index.js"] SCM["side_panel/chat-manager.js"] BG["background/index.js"] RL["background/react-loop.js"] end subgraph "代理端" SRV["server.js"] AUTH["auth.js"] SEC["security.js"] CL["crypto-lite.js"] end BR --> TS SRV --> AUTH SRV --> SEC SRV --> CL TS -.-> BR CM --> SS TB --> SS WM --> SS SP --> SS SCM --> SP BG --> RL
图示来源
- agent/src/server.js#L14-L14
- agent/src/auth.js#L181-L187
- agent/src/security.js#L760-L761
- agent/src/crypto-lite.js#L1-L32
- src/shared/secret.js#L1-L31
- src/storage/token-store.js#L1-L45
- src/background/token-recorder.js#L1-L37
- src/options/config-manager.js#L9-L9
- src/options/toolbox-shared.js#L7-L7
- src/side_panel/workspace-manager.js#L5-L5
- src/side_panel/index.js#L2265-L2265
- src/side_panel/chat-manager.js#L3987-L3987
- src/background/index.js#L1343-L1344
- src/background/react-loop.js#L1109-L1110
章节来源
- agent/src/server.js#L14-L14
- agent/src/auth.js#L181-L187
- agent/src/security.js#L760-L761
- agent/src/crypto-lite.js#L1-L32
- src/shared/secret.js#L1-L31
- src/storage/token-store.js#L1-L45
- src/background/token-recorder.js#L1-L37
- src/options/config-manager.js#L9-L9
- src/options/toolbox-shared.js#L7-L7
- src/side_panel/workspace-manager.js#L5-L5
- src/side_panel/index.js#L2265-L2265
- src/side_panel/chat-manager.js#L3987-L3987
- src/background/index.js#L1343-L1344
- src/background/react-loop.js#L1109-L1110
核心组件
- 配对认证模块(auth.js)
- 生成并轮换配对码,支持一次性使用与失败锁定。
- 维护最近一次成功认证时间,用于判断扩展是否在线。
- 提供 verifyToken 基于持久化配对表进行令牌校验。
- 安全网关(security.js)
- 路径沙箱:白名单目录、工作目录放行、硬阻止敏感文件/目录。
- 命令分级:黑名单绝对禁止、灰名单需确认、force 可跳过灰名单。
- 链式命令拆分、解释器内联载荷解析、命令替换检测。
- 密钥混淆(crypto-lite.js / secret.js)
- Base64 + enc: 前缀标记,兼容旧明文,非密码学安全但防一眼可见。
- Token 统计(token-store.js / token-recorder.js)
- 记录每次 API 调用的 prompt/completion/total tokens 与上下文窗口占比。
- 提供会话级、全局、按天、按模型、按调用类型的聚合查询。
- 统一令牌解码机制(新增)
- 在所有需要发送请求的模块中统一使用 decodeSecret 函数。
- 确保存储的加密令牌在发送前转换为明文,避免鉴权失败。
- 图片API密钥安全处理(新增)
- 在侧边栏初始化时解密imageApiKey并存储在state中。
- 监听storage变化时对新值进行解密处理。
- 通过消息传递将明文密钥传递给background脚本进行处理。
章节来源
- agent/src/auth.js#L30-L127
- agent/src/security.js#L62-L229
- agent/src/security.js#L285-L384
- agent/src/security.js#L691-L758
- agent/src/crypto-lite.js#L1-L32
- src/shared/secret.js#L1-L31
- src/storage/token-store.js#L13-L45
- src/background/token-recorder.js#L8-L37
- src/options/toolbox-shared.js#L145-L146
- src/side_panel/workspace-manager.js#L204-L205
- src/side_panel/index.js#L2265-L2265
- src/side_panel/index.js#L2324-L2324
架构总览
扩展端通过 background 脚本在 API 调用完成后收集 usage 信息,写入 IndexedDB;代理端 server.js 在请求入口处加载 auth 与 security 能力,完成配对、鉴权与命令/路径安全检查。
重要更新:现在所有扩展端模块在发送请求前都会使用 decodeSecret 对存储的令牌进行解码,确保 Authorization 头部携带的是明文令牌而非加密字符串。同时,图片API密钥的处理也遵循相同的安全模式。
sequenceDiagram participant Ext as "扩展端" participant BG as "background/token-recorder.js" participant DB as "storage/token-store.js" participant Srv as "agent/server.js" participant Auth as "agent/auth.js" participant Sec as "agent/security.js" participant Secret as "shared/secret.js" Note over Ext,Secret : 令牌解码流程 Ext->>Secret : "decodeSecret(encrypted_token)" Secret-->>Ext : "plain_token" Ext->>Srv : "HTTP 请求携带 Authorization : Bearer <plain_token>" Srv->>Auth : "verifyToken(token)" Auth-->>Srv : "extId 或 null" alt 未认证 Srv-->>Ext : "401 未认证" else 已认证 Srv->>Sec : "checkPath()/checkCommand()" Sec-->>Srv : "允许/拒绝/需确认" Srv-->>Ext : "业务响应" end Ext->>BG : "API 调用完成" BG->>DB : "recordTokenCall(...)" DB-->>BG : "写入结果" Note over Ext,Secret : 图片API密钥处理流程 Ext->>Secret : "decodeSecret(imageApiKey)" Secret-->>Ext : "plaintext_api_key" Ext->>BG : "传递明文API密钥" BG->>Srv : "视觉模型API调用"
图示来源
- agent/src/server.js#L513-L513
- agent/src/auth.js#L117-L127
- agent/src/security.js#L691-L758
- src/background/token-recorder.js#L16-L35
- src/storage/token-store.js#L24-L45
- src/shared/secret.js#L22-L30
- src/options/toolbox-shared.js#L145-L146
- src/side_panel/workspace-manager.js#L204-L205
- src/side_panel/index.js#L2265-L2265
- src/side_panel/index.js#L2324-L2324
详细组件分析
配对码与令牌认证流程
- 配对码生成
- 使用密码学安全的随机数生成 6 位字符(排除易混淆字符),初始启动即生成并在 TTL 周期内轮换。
- 若检测到已有配对且最近有活跃认证(默认 5 分钟窗口),则停止轮换;否则持续轮换以允许新设备配对。
- 配对请求处理
- 连续失败达到阈值后进入短时锁定,并立即轮换配对码使已观测码失效。
- 配对成功后立即轮换配对码,防止重复利用;同时保存扩展 ID 与随机生成的 token。
- 令牌校验
- verifyToken 遍历持久化配对表匹配 token,命中则更新 lastAuthTime 并返回 extId。
flowchart TD
Start(["开始"]) --> Gen["生成配对码<br/>startPairCodeRotation()"]
Gen --> Rotate{"是否活跃连接?"}
Rotate --> |是| StopRot["停止轮换"]
Rotate --> |否| NextRot["定时轮换配对码"]
NextRot --> PairReq["handlePairRequest(code, extensionId)"]
PairReq --> CheckLock{"是否在锁定窗口?"}
CheckLock --> |是| Deny["拒绝:过于频繁"]
CheckFail["配对码错误计数+1"] --> LockCheck{"达到失败阈值?"}
LockCheck --> |是| ForceRotate["立即轮换配对码并锁定"]
LockCheck --> |否| ReturnInvalid["返回无效配对码"]
ForceRotate --> ReturnInvalid
CheckLock --> |否| CheckCode{"配对码正确?"}
CheckCode --> |否| CheckFail
CheckCode --> |是| CheckPaired{"是否已配对?"}
CheckPaired --> |是| Rotated["轮换配对码并返回已有token"]
CheckPaired --> |否| SavePairing["保存扩展ID与token"]
SavePairing --> Rotated
Rotated --> End(["结束"])
图示来源
章节来源
令牌在服务端的集成与解码流程
- server.js 在请求入口处从 Authorization 头部提取 Bearer token,调用 verifyToken 获取 extId。
- 对需要认证的接口,若 verifyToken 返回空则拒绝访问。
- 配对接口 handlePairRequest 由 server.js 路由调用,并传入翻译函数 t。
重要更新:现在所有扩展端模块在发送请求前都会使用 decodeSecret 对存储的令牌进行解码:
sequenceDiagram
participant Client as "客户端"
participant ConfigMgr as "config-manager.js"
participant Toolbox as "toolbox-shared.js"
participant Workspace as "workspace-manager.js"
participant Secret as "shared/secret.js"
participant Server as "server.js"
participant Auth as "auth.js"
Note over Client,Secret : 统一的令牌解码流程
Client->>ConfigMgr : "getAgentConnection()"
ConfigMgr->>Secret : "decodeSecret(stored_token)"
Secret-->>ConfigMgr : "plain_token"
Client->>Toolbox : "agentApi(method, path, body)"
Toolbox->>Secret : "decodeSecret(stored_token)"
Secret-->>Toolbox : "plain_token"
Client->>Workspace : "getAgentConfig()"
Workspace->>Secret : "decodeSecret(stored_token)"
Secret-->>Workspace : "plain_token"
Client->>Server : "POST /pair (code, extensionId)"
Server->>Auth : "handlePairRequest(code, extensionId, t)"
Auth-->>Server : "{success, token?, message?}"
Server-->>Client : "配对结果"
Client->>Server : "GET /api/... (Authorization : Bearer <plain_token>)"
Server->>Auth : "verifyToken(token)"
Auth-->>Server : "extId 或 null"
Server-->>Client : "业务响应或401"
图示来源
- agent/src/server.js#L478-L478
- agent/src/server.js#L513-L513
- agent/src/auth.js#L117-L127
- agent/src/auth.js#L138-L179
- src/options/config-manager.js#L9-L9
- src/options/toolbox-shared.js#L145-L146
- src/side_panel/workspace-manager.js#L204-L205
章节来源
- agent/src/server.js#L478-L478
- agent/src/server.js#L513-L513
- agent/src/auth.js#L117-L127
- agent/src/auth.js#L138-L179
- src/options/config-manager.js#L9-L9
- src/options/toolbox-shared.js#L145-L146
- src/side_panel/workspace-manager.js#L204-L205
路径沙箱与命令分级管控
- 路径沙箱
- 硬阻止:代理配置文件、配对记录、日志、回收站等核心敏感文件/目录不可访问。
- 系统目录白名单:记忆存储目录可读写。
- 工作目录永远放行,但 realpath 仍会检查硬阻止,防止符号链接绕过。
- allowedPaths 白名单前缀匹配,并对 realPath 再次校验。
- 命令分级
- 黑名单:绝对禁止(如 rm -rf /、格式化磁盘、fork bomb、恶意管道执行等)。
- 灰名单:需用户确认(sudo、pip install、chmod 777、网络外联、kill、systemctl 等)。
- force 模式:跳过灰名单,但仍受黑名单约束。
- 链式命令拆分、包装器剥壳(sudo/doas/env/nohup 等)、解释器内联载荷(-c/-e、cmd /c /k、PowerShell -Command/-EncodedCommand)、命令替换 $(...) 与反引号检测。
flowchart TD
A["输入命令"] --> B["collectCommandScopes()<br/>原始串 + 拆分段 + 内联载荷 + 替换子段"]
B --> C{"黑名单命中?"}
C --> |是| D["deny不可绕过"]
C --> |否| E{"force 模式?"}
E --> |是| F["allow跳过灰名单"]
E --> |否| G{"灰名单命中?"}
G --> |是| H["confirm需用户确认"]
G --> |否| I["allow"]
图示来源
- agent/src/security.js#L62-L100
- agent/src/security.js#L109-L229
- agent/src/security.js#L285-L384
- agent/src/security.js#L653-L683
- agent/src/security.js#L691-L758
章节来源
- agent/src/security.js#L62-L100
- agent/src/security.js#L109-L229
- agent/src/security.js#L285-L384
- agent/src/security.js#L653-L683
- agent/src/security.js#L691-L758
Token 使用统计与审计
- 采集层:background/token-recorder.js 在 API 调用完成后读取 usage,计算 contextWindow,调用 storage/token-store.js 写入记录。
- 存储层:IndexedDB 中 tokenStats 表,包含 sessionId、model、promptTokens、completionTokens、totalTokens、contextWindow、contextUsageRate、callType、timestamp 等字段。
- 查询层:提供会话级汇总、全局汇总、按天聚合、按模型/调用类型分布、最近 N 条记录等接口。
classDiagram
class TokenRecorder {
+recordTokenUsage(params)
}
class TokenStore {
+recordTokenCall(record)
+getSessionTokenSummary(sessionId)
+getOverallTokenSummary()
+getDailyTokenSummary(days)
+getTokenSummaryByModel()
+getTokenSummaryByCallType()
}
TokenRecorder --> TokenStore : "写入记录"
图示来源
- src/background/token-recorder.js#L16-L35
- src/storage/token-store.js#L24-L45
- src/storage/token-store.js#L52-L98
- src/storage/token-store.js#L104-L137
- src/storage/token-store.js#L194-L224
- src/storage/token-store.js#L283-L310
- src/storage/token-store.js#L317-L345
章节来源
- src/background/token-recorder.js#L8-L37
- src/storage/token-store.js#L13-L45
- src/storage/token-store.js#L52-L98
- src/storage/token-store.js#L104-L137
- src/storage/token-store.js#L194-L224
- src/storage/token-store.js#L283-L310
- src/storage/token-store.js#L317-L345
加密工具函数与密钥管理
- 扩展端 shared/secret.js
- encodeSecret/decodeSecret:Base64 + enc: 前缀标记;无前缀视为旧明文原样返回,下次写入自动升级。
- 代理端 agent/src/crypto-lite.js
- 与扩展端约定一致,Node 环境使用 Buffer 进行 base64 编解码。
- 统一令牌解码实现(新增)
- config-manager.js:导入并使用 decodeSecret 处理存储的令牌。
- toolbox-shared.js:在 getAgentConnection 中统一解码令牌。
- workspace-manager.js:在 getAgentConfig 中统一解码令牌。
flowchart TD In["明文密钥"] --> Enc["encodeSecret()"] Enc --> Out["enc:base64(明文)"] Out --> Storage["chrome.storage.local"] Storage --> Dec["decodeSecret()"] Dec --> Plain["明文密钥"] Note["兼容规则:无前缀 → 原样返回"] Note2["统一解码:所有模块使用相同逻辑"]
图示来源
- src/shared/secret.js#L12-L30
- agent/src/crypto-lite.js#L13-L30
- src/options/config-manager.js#L9-L9
- src/options/toolbox-shared.js#L145-L146
- src/side_panel/workspace-manager.js#L204-L205
章节来源
- src/shared/secret.js#L1-L31
- agent/src/crypto-lite.js#L1-L32
- src/options/config-manager.js#L9-L9
- src/options/toolbox-shared.js#L145-L146
- src/side_panel/workspace-manager.js#L204-L205
统一令牌解码安全机制(新增)
安全漏洞修复:之前存在一个安全漏洞,某些模块直接将存储的加密令牌(enc:base64格式)发送给Agent服务器,导致鉴权失败(401错误)。现已在所有相关模块中实现了统一的令牌解码逻辑。
修复范围:
src/options/config-manager.js:导入 decodeSecret 函数src/options/toolbox-shared.js:在 getAgentConnection 中解码令牌src/side_panel/workspace-manager.js:在 getAgentConfig 中解码令牌
实现细节:
- 所有模块统一使用
decodeSecret(active.token)进行令牌解码 - 解码后的明文令牌用于构建 Authorization 头部
- 保持向后兼容,支持旧的明文令牌格式
安全措施:
- 令牌在存储时始终加密(enc:前缀 + base64编码)
- 仅在内存中使用明文令牌
- 请求发送后立即释放明文令牌引用
章节来源
- src/options/config-manager.js#L9-L9
- src/options/toolbox-shared.js#L145-L146
- src/side_panel/workspace-manager.js#L204-L205
图片API密钥安全处理机制(新增)
安全漏洞修复:侧边栏图片API密钥处理存在安全漏洞,当用户修改图片识别API密钥时,存储的加密密钥没有被正确解密,导致视觉模型API调用时携带密文密钥而返回401错误。
修复范围:
src/side_panel/index.js:在初始化时解密imageApiKey并监听storage变化src/side_panel/chat-manager.js:传递明文API密钥给background脚本src/background/index.js:接收并传递明文API密钥src/background/react-loop.js:使用明文API密钥进行视觉模型调用
实现细节:
- 侧边栏初始化时使用
decodeSecret(result.imageApiKey)解密存储的密钥 - 监听
chrome.storage.onChanged事件,对新值进行解密处理 - 通过消息传递将明文密钥传递给background脚本的apiParams
- background脚本将明文密钥传递给react-loop进行视觉模型调用
安全措施:
- 图片API密钥在存储时始终加密(enc:前缀 + base64编码)
- 仅在内存中使用明文密钥
- 密钥传递过程中保持明文状态,避免二次加密
sequenceDiagram
participant SP as "Side Panel"
participant BG as "Background"
participant RL as "React Loop"
participant Secret as "Shared Secret"
Note over SP,Secret : 图片API密钥处理流程
SP->>Secret : "decodeSecret(stored_imageApiKey)"
Secret-->>SP : "plaintext_api_key"
SP->>BG : "sendMessage({ imageApiKey : plaintext })"
BG->>RL : "apiParams.imageApiKey = plaintext"
RL->>RL : "config.apiKey = apiParams.imageApiKey"
RL->>RL : "调用视觉模型API"
图示来源
- src/side_panel/index.js#L2265-L2265
- src/side_panel/index.js#L2324-L2324
- src/side_panel/chat-manager.js#L3987-L3987
- src/background/index.js#L1343-L1344
- src/background/react-loop.js#L1109-L1110
章节来源
- src/side_panel/index.js#L2265-L2265
- src/side_panel/index.js#L2324-L2324
- src/side_panel/chat-manager.js#L3987-L3987
- src/background/index.js#L1343-L1344
- src/background/react-loop.js#L1109-L1110
依赖关系分析
- server.js 作为 HTTP 入口,依赖 auth.js 与 security.js 提供认证与安全能力。
- auth.js 依赖配置模块(loadConfig、loadPairings、savePairing)与 i18n。
- security.js 依赖 path/os/fs/promises 与配置模块,结合 i18n 输出多语言原因。
- token-recorder.js 依赖 token-store.js 与共享 logger。
- token-store.js 依赖 IndexedDB 封装 withStore。
- 新增依赖:所有涉及令牌处理的模块都依赖 shared/secret.js 中的 decodeSecret 函数。
- 新增依赖:侧边栏图片API密钥处理依赖完整的消息传递链路。
graph LR SRV["server.js"] --> AUTH["auth.js"] SRV --> SEC["security.js"] AUTH --> CFG["config.js"] SEC --> CFG REC["token-recorder.js"] --> TSTORE["token-store.js"] CM["config-manager.js"] --> SECRET["shared/secret.js"] TB["toolbox-shared.js"] --> SECRET WM["workspace-manager.js"] --> SECRET SP["side_panel/index.js"] --> SECRET SCM["side_panel/chat-manager.js"] --> SP BG["background/index.js"] --> RL["background/react-loop.js"]
图示来源
- agent/src/server.js#L14-L14
- agent/src/auth.js#L3-L5
- agent/src/security.js#L2-L6
- src/background/token-recorder.js#L4-L6
- src/storage/token-store.js#L1-L3
- src/options/config-manager.js#L9-L9
- src/options/toolbox-shared.js#L7-L7
- src/side_panel/workspace-manager.js#L5-L5
- src/side_panel/index.js#L2265-L2265
- src/side_panel/chat-manager.js#L3987-L3987
- src/background/index.js#L1343-L1344
- src/background/react-loop.js#L1109-L1110
章节来源
- agent/src/server.js#L14-L14
- agent/src/auth.js#L3-L5
- agent/src/security.js#L2-L6
- src/background/token-recorder.js#L4-L6
- src/storage/token-store.js#L1-L3
- src/options/config-manager.js#L9-L9
- src/options/toolbox-shared.js#L7-L7
- src/side_panel/workspace-manager.js#L5-L5
- src/side_panel/index.js#L2265-L2265
- src/side_panel/chat-manager.js#L3987-L3987
- src/background/index.js#L1343-L1344
- src/background/react-loop.js#L1109-L1110
性能与可扩展性
- 配对码轮换
- 基于配置的 TTL 定时刷新;当检测到活跃连接时停止轮换,减少不必要的随机数生成与日志输出。
- 路径检查
- 先做前缀快速匹配,再 realpath 校验,避免昂贵的系统调用;对 ENOENT 场景采用父目录回溯策略。
- 命令检查
- collectCommandScopes 深度封顶(默认 3),避免无限递归;仅对替换特征单独送检以减少误报。
- Token 统计
- 使用 IndexedDB 索引(sessionId、timestamp)缩小扫描范围;按天聚合与范围查询避免全表扫描。
- 令牌解码优化
- decodeSecret 函数轻量高效,仅在需要发送请求时调用。
- 解码结果缓存于内存变量中,避免重复解码。
- 图片API密钥处理优化
- 只在必要时解密图片API密钥,避免不必要的解密操作。
- 通过消息传递机制避免跨上下文的数据复制开销。
[本节为通用性能讨论,不直接分析具体文件]
故障排查指南
- 配对码频繁变化
- 检查是否有活跃连接(lastAuthTime 是否在 ACTIVE_WINDOW_MS 内);若无,则会自动轮换配对码。
- 检查 pairCodeTTL 配置是否过短。
- 配对失败锁定
- 连续失败达到 PAIR_FAIL_LIMIT 次后会进入 PAIR_LOCK_DURATION_MS 锁定;等待解锁后重试。
- 路径访问被拒
- 确认路径是否在 allowedPaths 或 workdir 内;检查是否存在符号链接指向硬阻止目录。
- 查看 reason 字段中的多语言提示,定位 isHardBlocked 或前缀匹配失败。
- 命令被拦截
- 黑名单命中将直接 deny;灰名单命中需用户确认或使用 force 模式(注意风险)。
- 使用 collectCommandScopes 调试实际送检的子命令范围。
- Token 统计缺失
- 检查 recordTokenUsage 是否被调用;确认 usage 对象存在 prompt_tokens 或 total_tokens。
- 查看 IndexedDB 中 tokenStats 表是否有记录;检查 timestamp 索引是否正常。
- 令牌鉴权失败(新增)
- 检查是否正确使用了 decodeSecret 函数对存储的令牌进行解码。
- 确认 Authorization 头部携带的是明文令牌而非 enc: 格式的密文。
- 查看浏览器开发者工具的 Network 面板,确认请求头中的 Authorization 字段。
- 图片API密钥鉴权失败(新增)
- 检查侧边栏是否正确解密了imageApiKey并存储在state中。
- 确认storage变化监听器是否正确处理了新值的解密。
- 检查background脚本是否正确接收并传递了明文API密钥。
- 查看视觉模型API调用的请求参数,确认apiKey字段是否为明文。
章节来源
- agent/src/auth.js#L30-L48
- agent/src/auth.js#L75-L102
- agent/src/auth.js#L138-L179
- agent/src/security.js#L109-L229
- agent/src/security.js#L691-L758
- src/background/token-recorder.js#L16-L35
- src/options/toolbox-shared.js#L145-L146
- src/side_panel/workspace-manager.js#L204-L205
- src/side_panel/index.js#L2265-L2265
- src/side_panel/index.js#L2324-L2324
结论
本项目的认证与安全体系围绕"配对码 + 令牌校验 + 路径/命令安全网关 + 统计审计"展开:
- 配对码流程具备抗暴破与一次性使用特性,配合活跃连接检测实现动态轮换。
- 安全网关通过黑名单/灰名单与链式命令解析,提供细粒度的命令分级管控。
- Token 统计提供多维度的审计能力,便于成本与使用分析。
- 密钥混淆方案简单有效,适合避免明文泄露的初级防护;生产环境应结合更严格的密钥管理策略。
- 最新安全加固:通过统一的令牌解码机制和图片API密钥安全处理,确保了所有模块在发送请求前都正确处理加密凭据,消除了鉴权失败的安全隐患。
[本节为总结性内容,不直接分析具体文件]
附录:安全配置清单
以下为通用安全配置建议,供部署与运维参考:
- TLS 证书
- 启用 HTTPS,使用受信任 CA 签发的证书;定期轮换证书与私钥。
- 禁用弱加密套件与过时协议版本(如 TLS1.0/1.1)。
- CORS 策略
- 明确允许的 Origin、方法与 Header;避免使用通配符 *。
- 对预检请求设置合理的缓存时长。
- 速率限制
- 针对配对接口与高频 API 设置 IP/用户维度的速率限制,防止暴力破解与资源耗尽。
- 安全头
- 设置 Strict-Transport-Security、X-Content-Type-Options、X-Frame-Options、Content-Security-Policy 等。
- 日志与审计
- 记录认证失败、路径/命令拒绝事件;对敏感操作进行脱敏与留存。
- 实施日志轮转策略(按大小/时间切分),保留期限符合合规要求。
- 令牌安全管理(新增)
- 确保所有模块使用统一的 decodeSecret 函数处理令牌。
- 定期检查 Authorization 头部是否正确携带明文令牌。
- 监控鉴权失败的日志,及时发现令牌处理问题。
- 图片API密钥安全管理(新增)
- 确保侧边栏正确解密并传递图片API密钥。
- 监控视觉模型API调用的鉴权状态。
- 定期检查storage中的imageApiKey字段是否正确加密。
[本节为通用实践建议,不直接分析具体文件]