Skip to content

认证与安全机制 ​

本文引用的源码文件

本文引用的文件

目录 ​

  1. 引言
  2. 项目结构与安全边界
  3. 核心安全组件
  4. 系统架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与资源限制
  8. 故障排查指南
  9. 结论与安全最佳实践
  10. 附录:curl 示例与错误对照

引言 ​

本文面向 Agent HTTP API 的认证与安全机制,聚焦以下目标:

  • 说明 Bearer Token 验证流程、配对码生成、扩展端配对、Token 轮换与过期处理。
  • 解释路径白名单机制,包括 allowedPaths 配置语义与 checkPath 安全检查逻辑。
  • 描述命令安全分级系统,包括黑名单过滤、灰名单确认、命令白名单/强制放行与执行权限控制。
  • 说明 CORS 跨域策略:仅允许 chrome-extension:// 来源访问。
  • 提供完整认证流程图、错误响应格式和安全最佳实践建议。
  • 给出 curl 示例,展示认证请求与常见安全错误的处理方法。

本项目采用双进程架构:Chrome 扩展端(Manifest V3)通过本地 HTTP/WebSocket 调用 Agent(Node.js)。Agent 负责文件系统、命令执行、技能、MCP、长期记忆与 RAG 等能力;扩展端负责用户交互、工具编排与本地代理客户端通信。

章节来源

项目结构与安全边界 ​

Agent 的安全入口集中在 HTTP 服务器路由中,所有需要认证的接口在解析业务参数前统一进行 Bearer Token 校验;无需认证的接口(如健康检查、配对)则受 CORS 与最小信息暴露策略保护。

graph TB
Client["浏览器或本地脚本"] --> Server["Agent HTTP 服务器<br/>server.js"]
Server --> Auth["认证模块<br/>auth.js"]
Server --> Security["安全模块<br/>security.js"]
Server --> Executor["命令执行器<br/>executor.js"]
Server --> Config["配置模块<br/>config.js"]
Server --> Memory["记忆路由<br/>memory/routes.js"]
Server --> MCP["MCP 注册表<br/>mcp/registry.js"]
Server --> Skill["技能注册表<br/>skill/registry.js"]

图表来源

章节来源

核心安全组件 ​

  • 认证模块:负责配对码生成、扩展端配对、Token 验证与活跃连接窗口管理。
  • 安全模块:负责路径白名单校验、硬阻止目录保护、命令分级管控。
  • HTTP 服务器:统一处理 CORS、认证、请求体大小限制、文件上传与业务路由。
  • 配置模块:提供 workdir、allowedPaths、pairCodeTTL、commandTimeout、fileMaxSize 等关键配置项。
  • 扩展端客户端:发起配对、保存 Token、携带 Authorization 头调用受保护接口。

章节来源

系统架构总览 ​

Agent 的认证与安全流程可概括为:

  1. 扩展端获取当前配对码并调用 /api/pair 完成配对。
  2. 配对成功后获得 Token,后续请求携带 Authorization: Bearer <token>。
  3. 服务器对每个请求先做 CORS 预检与 Origin 校验,再解析 URL 与 body。
  4. 无需认证的接口直接返回最小必要信息;需要认证的接口先验 Token。
  5. 文件类接口使用 checkPath 校验路径是否在白名单内。
  6. 命令类接口使用 checkCommand 进行黑名单/灰名单分级判定。
sequenceDiagram
participant Ext as "扩展端"
participant Srv as "Agent 服务器"
participant Auth as "认证模块"
participant Sec as "安全模块"
Ext->>Srv : POST /api/pair {code, extensionId}
Srv->>Auth : handlePairRequest(code, extensionId)
Auth-->>Srv : {success, token|error}
Srv-->>Ext : {success, token|error}
Ext->>Srv : GET /api/status/detail (Authorization : Bearer token)
Srv->>Auth : verifyToken(token)
Auth-->>Srv : extId|null
alt 认证成功
Srv-->>Ext : {success, version, workdir, allowedPaths, ...}
else 认证失败
Srv-->>Ext : {success : false, error : "noToken"|invalidToken}
end
Ext->>Srv : POST /api/fs/read/write/list/delete/download (path)
Srv->>Sec : checkPath(path)
Sec-->>Srv : {allowed,resolved|reason}
alt 路径允许
Srv-->>Ext : 业务结果
else 路径拒绝
Srv-->>Ext : {success : false, error : reason}
end
Ext->>Srv : POST /api/exec (command, force?)
Srv->>Sec : checkCommand(command, force)
Sec-->>Srv : {safe,level,reason}
alt allow/deny
Srv-->>Ext : 执行结果或拒绝
else confirm
Srv-->>Ext : {needConfirm : true, reason}
end

图表来源

详细组件分析 ​

Bearer Token 认证与配对码机制 ​

  • 配对码生成:使用密码学安全的随机字节生成 6 位字母数字配对码,排除易混淆字符。
  • 配对码轮换:启动时立即生成一次;定时按 pairCodeTTL 刷新;当存在配对记录且最近 5 分钟内有过认证,则停止刷新;否则继续刷新以允许新扩展配对。
  • 配对请求:校验 code 与 extensionId;连续失败 5 次后锁定 60 秒并立即轮换配对码;配对成功后立即轮换配对码,防止重复利用。
  • Token 验证:每次成功认证更新 lastAuthTime;服务器从配对记录中查找匹配 token,返回扩展 ID。
  • 已配对扩展横向防护:/api/status/detail 不再下发 pairCode,避免已配对端横向获取其他扩展的配对码。
flowchart TD
Start(["启动 Agent"]) --> GenCode["生成初始配对码"]
GenCode --> Timer["启动 TTL 定时器"]
Timer --> CheckActive{"有配对且最近活跃?"}
CheckActive --> |是| StopRotate["停止轮换配对码"]
CheckActive --> |否| RotateCode["轮换新配对码"]
RotateCode --> Timer
StopRotate --> Timer
PairReq["收到 /api/pair 请求"] --> Validate["校验 code 与 extensionId"]
Validate --> ValidCode{"配对码正确?"}
ValidCode --> |否| IncFail["失败计数+1"]
IncFail --> LockCheck{"达到失败阈值?"}
LockCheck --> |是| Lock["锁定 60 秒并轮换配对码"]
LockCheck --> |否| ReturnErr["返回错误"]
ValidCode --> |是| SavePairing["保存扩展 Token 并轮换配对码"]
SavePairing --> ReturnToken["返回 Token"]

图表来源

章节来源

路径白名单与安全检查函数 checkPath ​

checkPath 是文件类接口的核心安全门控,其逻辑如下:

  1. 输入校验与 ~ 展开。
  2. 路径格式规整:处理 MSYS/Git Bash 风格路径、盘符大写、反斜杠统一。
  3. 绝对路径解析与工作目录合并。
  4. 硬阻止检查:.ai-helper-agent 下的敏感配置文件、日志、回收站、技能状态等不可绕过。
  5. 系统目录白名单:记忆存储目录始终允许读写。
  6. 工作目录永远放行:即使未出现在 allowedPaths,也允许访问当前工作目录,但需 realpath 防符号链接绕过。
  7. allowedPaths 白名单匹配:若配置为空则回退到工作目录;否则使用前缀匹配快速判断。
  8. realpath 二次校验:防止符号链接绕过,并对 realPath 再次做硬阻止与前缀检查。
  9. 最终返回 {allowed, resolved|reason}。
flowchart TD
Enter(["进入 checkPath"]) --> Normalize["路径格式规整与 ~ 展开"]
Normalize --> Resolve["解析绝对路径"]
Resolve --> HardBlock{"命中硬阻止目录?"}
HardBlock --> |是| DenyHard["拒绝:禁止访问 Agent 敏感文件"]
HardBlock --> |否| MemoryCheck{"是否记忆存储目录?"}
MemoryCheck --> |是| AllowMemory["允许:记忆目录"]
MemoryCheck --> |否| WorkdirCheck{"是否在工作目录下?"}
WorkdirCheck --> |是| RealpathWorkdir["realpath 防符号链接绕过"]
RealpathWorkdir --> AllowWorkdir["允许:工作目录"]
WorkdirCheck --> |否| AllowedPathsCheck{"是否在 allowedPaths 白名单?"}
AllowedPathsCheck --> |否| DenyNotAllowed["拒绝:路径不在允许目录"]
AllowedPathsCheck --> |是| RealpathAllowed["realpath 二次校验"]
RealpathAllowed --> HardBlockReal{"realPath 命中硬阻止?"}
HardBlockReal --> |是| DenyHardReal["拒绝:禁止访问 Agent 敏感文件"]
HardBlockReal --> |否| PrefixReal["realPath 前缀匹配"]
PrefixReal --> AllowFinal["允许:路径有效"]

图表来源

章节来源

命令安全分级系统 ​

命令安全分为三个层级:

  • 黑名单(deny):绝对禁止,force 不可绕过。包括递归删除系统目录、格式化磁盘、覆盖 /etc/passwd、fork bomb、shebang 直接执行、管道执行 shell 等。
  • 灰名单(confirm):需要真实用户确认,force 可跳过。包括 sudo/doas/runas、全局 npm install、pip install/uninstall、chmod 777、rm -rf、git push -f、shutdown/reboot、eval、dd/shred/truncate、chmod/chown、curl/wget/ssh 等网络与进程操作、脚本解释器执行外部文件等。
  • 白名单(allow):通过安全检查,直接执行。

命令扫描会逐段拆分链式命令、剥壳包装器(sudo/nohup/env 等)、提取解释器内联载荷(-c/-e、/c /k、PowerShell -Command/-EncodedCommand),并单独扫描命令替换($( ) 与反引号)中的子命令。黑名单始终生效;灰名单在 force 模式下跳过。

flowchart TD
CmdEnter(["进入 checkCommand"]) --> Trim["去除空白"]
Trim --> Scopes["收集子命令范围<br/>原始串 + 链式拆分 + 包装器剥壳 + 内联载荷 + 命令替换"]
Scopes --> Blacklist{"命中黑名单?"}
Blacklist --> |是| DenyCmd["拒绝:dangerous command"]
Blacklist --> |否| ForbiddenFile{"命令包含 Agent 敏感文件?"}
ForbiddenFile --> |是| DenyForbidden["拒绝:forbidden agent file"]
ForbiddenFile --> |否| ForceCheck{"force 模式?"}
ForceCheck --> |是| AllowForce["允许:用户已确认"]
ForceCheck --> |否| Graylist{"命中灰名单?"}
Graylist --> |是| ConfirmCmd["确认:需要用户确认"]
Graylist --> |否| AllowSafe["允许:安全命令"]

图表来源

章节来源

CORS 跨域策略 ​

CORS 策略严格限制为仅允许 chrome-extension:// 来源:

  • getAllowedOrigin 仅当 origin 以 chrome-extension:// 开头时返回该 origin。
  • JSON 响应辅助函数 jsonResponse 仅在允许 origin 时设置 Access-Control-Allow-Origin 与 Vary: Origin。
  • OPTIONS 预检请求同样遵循该策略。
  • 恶意网页无法读取无认证端点(如 /api/status、/api/pair)的响应;非浏览器客户端(curl/脚本)不受 CORS 限制仍可访问。
flowchart TD
Req["HTTP 请求"] --> OriginCheck{"Origin 是否存在?"}
OriginCheck --> |否| NoACAO["不设置 ACAO"]
OriginCheck --> |是| ChromeExt{"是否 chrome-extension:// ?"}
ChromeExt --> |否| NoACAO
ChromeExt --> |是| SetACAO["设置 Access-Control-Allow-Origin = Origin"]
SetACAO --> Response["返回响应"]
NoACAO --> Response

图表来源

章节来源

扩展端与 Agent 端的认证协作 ​

扩展端在配对成功后保存 Token,并在后续请求中携带 Authorization: Bearer <token>。options 面板的通用 Agent API 请求函数也会自动注入该头部,并对记忆写入端点附加 X-Memory-Caller: user 以声明可信来源。

sequenceDiagram
participant UI as "扩展端 UI"
participant Client as "local-agent-client.js"
participant Options as "toolbox-shared.js"
participant Server as "Agent 服务器"
UI->>Client : 触发配对
Client->>Server : POST /api/pair
Server-->>Client : {success, token}
Client->>Client : 保存 state.agentToken
UI->>Options : 调用 agentApi(method, path, body)
Options->>Options : 注入 Authorization : Bearer token
Options->>Server : HTTP 请求
Server-->>Options : JSON 响应

图表来源

章节来源

依赖关系分析 ​

Agent 的安全依赖关系如下:

  • server.js 依赖 auth.js 进行 Token 验证与配对码管理。
  • server.js 依赖 security.js 进行路径与命令安全检查。
  • security.js 依赖 config.js 获取 workdir、allowedPaths、MEMORY_DIR 等配置。
  • executor.js 依赖 security.js 的命令分级结果决定是否执行或要求确认。
  • memory/routes.js 依赖 X-Memory-Caller 头区分模型与用户来源。
graph LR
Server["server.js"] --> Auth["auth.js"]
Server --> Security["security.js"]
Server --> Executor["executor.js"]
Security --> Config["config.js"]
Executor --> Security
Memory["memory/routes.js"] --> Server

图表来源

章节来源

性能与资源限制 ​

  • 请求体大小限制:JSON body 最大 200MB,multipart/form-data 同样限制。
  • 流式上传:按接收字节累计超限即中断写入并清理半成品文件。
  • 文件读取大小限制:默认 50MB,可通过 fileMaxSize 配置调整。
  • 搜索最大结果数:单次搜索最多 5000 条。
  • 重启/更新冷却时间:10 秒冷却,防止频繁操作导致 DoS。
  • 命令超时:默认 300 秒,可通过 commandTimeout 配置调整。

章节来源

故障排查指南 ​

常见认证与安全错误及处理建议:

  • 401 无 Token:检查是否携带 Authorization: Bearer <token>。
  • 403 Token 无效:检查 Token 是否正确、是否过期、是否被轮换。
  • 403 路径不在允许目录:检查 allowedPaths 配置是否包含目标路径。
  • 403 禁止访问 Agent 敏感文件:检查是否尝试访问 .ai-helper-agent 下的敏感文件或通过符号链接绕过。
  • 400 文件过大:检查 fileMaxSize 与上传内容大小。
  • 400 命令无效:检查命令是否为空或仅含空白字符。
  • 403 危险命令被拦截:查看命令是否命中黑名单;如需执行,使用 force 模式并经用户确认。
  • 409 操作进行中:等待冷却时间后重试。
  • 429 操作过于频繁:根据提示等待指定秒数。

章节来源

结论与安全最佳实践 ​

  • 始终使用配对码完成一次性配对,避免 Token 泄露。
  • 不要将 Agent 监听地址绑定到 0.0.0.0,除非明确需要远程访问并已做好网络隔离。
  • 合理配置 allowedPaths,仅开放必要目录;工作目录应始终可控。
  • 谨慎使用 force 模式执行命令,确保用户已确认高风险操作。
  • 定期轮换配对码与检查 Token 有效性,避免长期使用同一 Token。
  • 监控日志中的认证失败、路径拒绝与命令拦截事件,及时发现异常行为。
  • 保持 Agent 版本与扩展端版本同步,确保接口契约一致。

[本节为总结性内容,不直接分析具体文件]

附录:curl 示例与错误对照 ​

配对请求 ​

bash
curl -X POST http://127.0.0.1:18910/api/pair \
  -H "Content-Type: application/json" \
  -d '{"code":"ABCD12","extensionId":"chrome-extension-id"}'

可能返回:

  • {success:true, token:"..."}:配对成功。
  • {success:false, error:"tooFrequent"}:配对失败锁定中。
  • {success:false, error:"invalidCode"}:配对码错误或已轮换。

健康检查(无需认证) ​

bash
curl http://127.0.0.1:18910/api/status

返回平台信息与运行状态,不包含敏感主机信息。

带 Token 的状态详情 ​

bash
curl http://127.0.0.1:18910/api/status/detail \
  -H "Authorization: Bearer YOUR_TOKEN"

返回 workdir、allowedPaths、commandTimeout、fileMaxSize 等配置信息。

文件读取(需认证 + 路径白名单) ​

bash
curl -X POST http://127.0.0.1:18910/api/fs/read \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"path":"/absolute/path/to/file.txt"}'

可能返回:

  • {success:true, content:"...", size:123}:读取成功。
  • {success:false, error:"路径不在允许目录"}:路径不在 allowedPaths。
  • {success:false, error:"禁止访问 Agent 敏感文件"}:命中硬阻止目录。

命令执行(需认证 + 安全分级) ​

bash
curl -X POST http://127.0.0.1:18910/api/exec \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"command":"ls -la","force":false}'

可能返回:

  • {safe:true, level:"allow"}:直接执行。
  • {safe:false, level:"confirm", reason:"..."}:需要用户确认。
  • {safe:false, level:"deny", reason:"..."}:黑名单拒绝,不可绕过。

常见错误对照表 ​

HTTP 状态业务含义常见原因处理建议
401缺少 Token未携带 Authorization 头添加 Authorization: Bearer <token>
403Token 无效Token 错误、已轮换或不存在重新配对或检查 Token 来源
403路径拒绝不在 allowedPaths 或命中硬阻止检查白名单配置与路径安全性
400请求体过大JSON/body 超过 200MB减小请求体或使用流式上传
400命令无效命令为空或仅空白检查命令参数
409操作进行中重启/更新冷却中等待 10 秒后重试
429操作过于频繁冷却时间内重复请求根据提示等待指定秒数

章节来源