Files
SQLBot/docs/agents/security.md
T

6.1 KiB
Raw Blame History

安全 Agent 说明

原则

  • LLM 输出、SQL、文件名、路径、Host 头、路由参数、第三方回传数据和前端消息都不是可信输入。
  • 新接口默认拒绝;先认证、再授权、再校验资源归属,最后执行业务。
  • 发现现有绕过路径时优先收敛授权语义,不要只在单个 URL 上打补丁。
  • 涉及以下任何区域,必须补充或更新回归测试,并运行 backend/tests/ 中的相关守卫。

API 权限

  • 使用 CurrentUser / SessionDep 获取身份和会话,不信任请求体中的用户或工作空间 ID。
  • 资源型接口使用 @require_permissions(...),并确认:
    • type 指向正确资源;
    • keyExpression 能取到真实资源 ID;
    • 列表语义不会被单个资源绕过;
    • 管理员、工作空间管理员和普通用户路径都明确。
  • 权限表达式引用的参数缺失、解析失败或归属不匹配时必须拒绝,不能回退为直接执行处理函数。
  • 子资源归属从服务端记录推导并校验完整关系(如字段 → 表 → 数据源 → 工作空间);请求中的 ds_id、oid 仅为待校验输入。不能仅验证调用者有权访问所提供的数据源,再按任意表/字段 ID 执行操作。
  • 批量接口明确整批拒绝还是仅操作有权记录,并测试混合归属输入;单项、批量、同步、导出等入口应遵循相同授权边界。
  • 手写查询归属时,同时校验:
    • 资源存在;
    • 资源属于当前工作空间;
    • 资源属于当前用户或其授权范围;
    • 助手上下文没有切换到其他工作空间。
  • oid 和 workspace_id 都表示工作空间 ID;不要把两者当成不同授权域。
  • 高级助手动态数据源只允许既有动态类型走动态数据源例外;本地 CoreDatasource 仍必须校验工作空间归属。

SQL 生成与执行

修改主流程时应满足以下安全顺序;需在实际入口和调用链验证,不能把本清单当作现状已安全的证明:

  1. 只把允许的表和字段元数据提供给模型;
  2. 解析模型返回 JSON 并提取 SQL;
  3. 用 sqlglot 提取真实表名并排除 CTE 别名;
  4. 对照允许表集合拒绝未授权表;
  5. 按用户、助手和页面嵌入场景应用行权限或动态 SQL 变换;
  6. 校验并保存最终 SQL;
  7. 执行最终 SQL 并保存结果。

额外要求:

  • 不要信任模型返回的 tables 字段替代真实 SQL 解析。
  • 行权限拼接沿用白名单逻辑运算符和 _escape_sql_value,不要引入新的字符串拼接入口。
  • 保持 SQL 行数限制和 SQLBOT_ALLOW_METADATA_QUERIES 默认关闭语义;不要为了调试全局开启元数据查询。
  • 动态 SQL 生成后仍必须走同一解析、校验和保存路径。
  • 数据源连接配置解密只发生在服务端执行路径,不进入日志或 API 响应。

认证、Host 与嵌入

  • 修改 backend/main.py 的中间件顺序时,验证实际请求执行顺序(不能只看注册顺序);HostValidationMiddleware 必须在认证/业务使用 Host 前拒绝非法值,并回归预检与正常请求。
  • Host 只允许合法域名 / IPv4 / IPv6 形态,不能包含 /、@ 或空白。
  • 认证和助手 token 头由后端中间件与前端 request interceptor 处理;不要新增手工传递或复制 token 的路径。
  • 页面嵌入协议必须保持:
    • 仅 AssistantModel.type == 4 可用 embedded 协议;
    • 先提取目标助手,再用 app_secret 验证签名;
    • 管理员账号拒绝通过 embedded token 使用;
    • 账号状态和工作空间归属仍需校验。
  • 修改助手 domain、app_id、app_secret 或类型时,同时考虑目标系统信任边界和跨工作空间访问。
  • 前端 postMessage 证书流程不要降级为无请求绑定、无来源约束或永久有效证书。

文件与路径

  • 不信任上传文件名、扩展名、MIME、sheet 名或用户提供的 filePath。
  • 上传必须限制类型和大小,落盘使用服务端生成的文件名或 opaque ID。
  • 读取用户可控路径前,解析真实路径后用 os.path.commonpath 等验证其仍位于允许目录内,或通过已授权的内部 ID 映射路径;不使用字符串前缀判断。校验到打开之间不得允许不可信方替换路径或符号链接。
  • 下载前先校验权限和服务端文件实际路径的目录归属,包括符号链接解析;os.path.basename 只适合清理下载展示名,FileResponse 只负责传输,两者都不能替代路径授权。响应不回显内部绝对路径。
  • Excel/CSV 解析错误不能变成可猜测的内部路径信息。

前端渲染

  • 不直接在组件中调用 axios,避免绕开认证、语言、助手证书和错误处理。
  • Markdown 渲染保持 html: false,代码高亮必须转义。
  • 新增富文本 / HTML 渲染必须走既有安全工具和组件;不要添加未净化 v-html。
  • 链接、图片和远程脚本必须限制协议和来源,不允许 javascript: 或用户控制的服务端地址。
  • xpack 静态脚本保留缓存穿透参数和失败处理;不要把商业脚本或密钥复制进前端源码。

日志与敏感信息

  • 不记录 token、密码、API key、数据源明文连接串、SQL 凭据、助手 secret 或完整敏感配置。
  • 异常响应面向用户时使用后端 i18n 错误;内部 traceback 只进入受控日志。
  • 安全测试样本可以包含攻击载荷,但不得包含真实可用凭据或内部地址。

必测场景

按本次涉及的入口选择相关场景;不要求每次安全改动执行下列全部类别,但必须说明未覆盖的相关风险:

  • 未登录、无权限、资源不存在、跨工作空间访问;
  • 管理员、工作空间管理员、普通用户、助手用户;
  • Host 头携带路径、@、空白等污染形态;
  • SQL 引用未授权表、CTE 别名、动态 SQL 和行权限边界;
  • embedded token 错误助手类型、错误签名、管理员账号和无效账号;
  • 上传路径穿越、非法扩展、超限大小和重复扩展名;
  • 前端错误传播和未净化内容渲染。