Files
SQLBot/docs/agents/security.md
T

92 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 安全 Agent 说明
## 原则
- LLM 输出、SQL、文件名、路径、Host 头、路由参数、第三方回传数据和前端消息都不是可信输入。
- 新接口默认拒绝;先认证、再授权、再校验资源归属,最后执行业务。
- 发现现有绕过路径时优先收敛授权语义,不要只在单个 URL 上打补丁。
- 涉及以下任何区域,必须补充或更新回归测试,并运行 `backend/tests/` 中的相关守卫。
## API 权限
- 使用 `CurrentUser` / `SessionDep` 获取身份和会话,不信任请求体中的用户或工作空间 ID。
- 资源型接口使用 `@require_permissions(...)`,并确认:
- `type` 指向正确资源;
- `keyExpression` 能取到真实资源 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 错误助手类型、错误签名、管理员账号和无效账号;
- 上传路径穿越、非法扩展、超限大小和重复扩展名;
- 前端错误传播和未净化内容渲染。