跳转至

w4_05 · 安全审查清单(对 projects/kbprojects/aggregator 各做一遍)

目标:列出 ≥5 处可改进项,修掉 3 处并提交(commit 前缀 fix(security):refactor:)。不确定的条目写"待确认 + 理由",不要猜。

一、输入与解析

  • 所有外部输入(命令行参数、环境变量、HTTP 请求体/查询/头、文件内容)都经过 Pydantic 或显式类型校验,而不是直接 dict["key"]
  • 没有 eval / exec / pickle.loads / yaml.load(非 safe)处理不可信数据
  • 正则不会灾难性回溯(嵌套量词如 (a+)+、对超长输入的 .*);对用户提供的 --regex 有长度/超时兜底
  • 数字参数有范围(ge/le),字符串有长度上限,列表有条数上限

二、文件与路径

  • 用户给的路径先 Path(...).resolve(),再检查是否仍在允许的根目录之下(path.is_relative_to(root)),防路径穿越 ../../etc/passwd
  • 所有文本读写显式 encoding="utf-8";写关键文件走"临时文件 + os.replace"
  • 不把用户输入直接拼进文件名(清洗或用 id)
  • 临时文件用 tempfile,不用 /tmp/固定名

三、命令与外部进程

  • subprocess 一律列表参数、shell=False、显式 timeout
  • 不用 sys.executable 以外的写死解释器路径;不用 os.system
  • 子进程的输出上限可控(不会因为对方无限输出而耗尽内存)

四、数据库

  • SQL 全部参数化(?),没有 f-string 拼 SQL;LIKE 的通配符来自用户时考虑转义 % _
  • 事务边界清晰(with conn:),失败会回滚
  • 数据库文件不在仓库里(*.db.gitignore

五、密钥与配置

  • 代码里没有任何真实密钥/令牌/密码(rg -n "sk-|token|password|secret" src 检查)
  • .env.gitignore,仓库只有 .env.example;Git 历史里也没有(git log -p -S "sk-"
  • 日志不打印密钥、完整请求头、用户隐私;错误响应不带堆栈
  • 配置缺失时"启动即失败"而不是带着默认密钥跑

六、网络(aggregator / Notebook Service)

  • 每个 HTTP 请求都有超时;重试只针对幂等请求与 5xx/网络错误
  • 抓取的 URL 来自可信列表或经过校验(禁止 file://、内网地址等,防 SSRF)
  • 服务默认只监听 127.0.0.1;对外暴露前先有鉴权
  • CORS 不用 * + 凭证;写操作需要 X-API-Key(或更强的机制)
  • 依赖锁定在 uv.lock;知道 uv tree / pip-audit 能查已知漏洞

七、错误与日志

  • 没有 except: pass / except Exception: pass
  • logger.exception 用在"意外错误",logger.warning 用在"可恢复的预期错误"
  • 日志文件 UTF-8、有轮转,不无限增长

作答区

kb

# 发现(文件:行) 风险 修法 状态(已修 / 待办 / 待确认)
1
2
3
4
5

aggregator

# 发现(文件:行) 风险 修法 状态
1
2
3
4
5

服务器实操记录

  • 在 H20 上 git clone + uv syncuv run aggregator serve-stub --port 8001 起服务
  • 本机 ssh -L 8001:127.0.0.1:8001 user@host,浏览器打开 http://localhost:8001/health 看到 {"status": "ok"}
  • 记录:Linux 与 Windows 上 bench --count 30 的三组数字差异,写进周日志

提示(不要先看):常见发现包括——kb import 对任意目录递归读取没有大小/数量上限;kb search --regex 直接编译用户正则;aggregator 的 --base-url 未校验协议;导出路径未限制在工作目录内;日志级别 DEBUG 时会打印完整 URL(可能含查询串里的令牌)。