w4_05 · 安全审查清单(对 projects/kb 与 projects/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 sync,uv 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(可能含查询串里的令牌)。