Files
blackbird/docs/security/db_SECURITY_AUDIT_20260801.md
qing 5fbe3ed5e4 docs(security): 更新全部模块审计报告,添加代码验证记录
逐模块对照实际代码验证审计报告中的问题修复状态,添加代码验证记录、逐条验证结果、修复率统计。合并aibox两份审计报告,删除重复文件。修复率:confs 61% > dnfs 60% > ai_review 50% > smtp 37.5% > db 33% > core 12.5% > gateway 12.5% > pymsg 6.25% > static 5% > captcha/aibox/BotOps 0%
2026-08-03 14:12:45 +08:00

6.6 KiB
Raw Permalink Blame History

db 模块安全审计报告

审计日期: 2026-08-01
审计范围: dbv2.py、db_tools.py、log_client 相关
代码版本: dev_qing 分支


修复进度

优先级 总数 已修复 部分修复 未修复
P0 1 0 1 0
P1 3 0 1 2
P2 2 1 0 1
合计 6 1 2 3

🔴 P0 — 严重问题

P0-1: 零认证对外开放完整 CRUD(依赖 127.0.0.1 网络隔离)

  • 位置: dbv2.py L180、L191-196、L323-406
  • 当前状态: ⚠️ 部分修复
    • ✅ 默认监听 127.0.0.1(dbv2.py L180),Docker 也绑定到 127.0.0.1
    • ✅ 配置通过 confs + 环境变量两层加载,配置完整性校验(dbv2.py L118-129)
    • ❌ 仍无任何认证机制(RpcServer 无 auth 回调)
    • ❌ SELECT 无默认 LIMIT:_do_select (L364-366) limit 参数可选,客户端可省略以获取全表数据
    • ❌ UPDATE/DELETE 不强制要求 WHERE:_do_update (L391-394) 和 _do_delete (L400-403) 仅在 where_cond 非空时添加 WHERE 子句,可执行无条件全表更新/删除
    • ❌ 无表级/操作级权限控制
  • 修复建议:
    1. 确保管理接口仅监听 127.0.0.1 ✅ 已实现
    2. 添加 API Token 认证(预共享密钥,所有调用需携带 _auth 字段)
    3. SELECT 强制添加 LIMIT 上限(默认 1000 条),防止拖库
    4. 添加操作权限:日志写入只允许 insert,禁止 delete/truncate
    5. 拒绝无条件 UPDATE/DELETE(必须带 where 条件)
    6. DDL 操作仅限本地运维工具,RPC 接口完全禁用

🟠 P1 — 高危问题

# 问题 状态 说明
P1-1 db_tools.py 运维工具存在 SQL 字符串拼接风险 ⚠️ 部分修复 db_tools.py 使用参数化查询(executemany + 占位符),表名来自 sqlite_master 查询非用户输入;但 _view_db.sqlite3.py L53 cur.execute(args.sql) 支持自由 SQL(本地工具,可接受风险)
P1-2 无操作审计日志 ❌ 未修复 _handle_execute (L323-344) 处理 CRUD 操作时无任何审计记录,无法追溯谁在何时修改了什么数据
P1-3 Logs 表自动清理可被利用销毁证据 ❌ 未修复 _do_cleanup (L493-528) 按时间和条数清理,攻击者可通过大量写日志触发 max_records 裁剪,删除攻击痕迹

🟡 P2 — 中危问题

# 问题 状态 说明
P2-1 日志表自动清理保留策略可配置化 ✅ 已修复 dbv2.py L65-69 通过 [logs] 配置段支持 retention_days、max_records、cleanup_interval,通过 confs/db.ini + 环境变量配置
P2-2 错误信息可能泄露表结构/字段名给调用方 ❌ 未修复 _coerce_value (L262-265) 返回 "列 {column.name} 的日期时间值无法解析..." 暴露列名;_handle_execute (L332) 返回 "表加载失败: {e}" 暴露表名

✅ 已有安全机制

  1. ✅ SQLAlchemy Core 参数化查询:核心 CRUD 路径使用表反射 + 参数化,零 SQL 注入风险 (dbv2.py L346-406)
  2. ✅ 仅监听 127.0.0.1:不对外暴露 (dbv2.py L180)
  3. ✅ 集中式日志 fail-safe:db 不可用时静默丢弃,不阻塞业务 (example_log_client.py L57-106)
  4. ✅ 自动提交/回滚:异常时自动回滚事务
  5. ✅ 日期/时间适配:ISO 8601 处理,"$now" 哨兵 (dbv2.py L242-287)
  6. ✅ 日志自动清理:后台线程按时间+条数清理,防止磁盘占满 (dbv2.py L480-528)
  7. ✅ log_client 健壮性:异步队列、后台线程、fail-safe、队列上限 10000 (example_log_client.py L38-41)
  8. ✅ 配置白名单校验:_merge_ini 仅覆盖已知 section/key,防止意外字段注入 (dbv2.py L73-81)
  9. ✅ 配置完整性校验:启动时检查所有必需配置项,缺失则退出 (dbv2.py L118-129)
  10. ✅ SQLite PRAGMA 优化:WAL 模式 + NORMAL 同步 + busy_timeout + mmap (dbv2.py L139-155)
  11. ✅ 表反射线程安全:double-check 锁机制防止并发反射竞态 (dbv2.py L225-239)

修复路线图

立即(24小时)

  • SELECT 添加强制默认 LIMIT 上限(防止拖库)
  • UPDATE/DELETE 强制执行 WHERE 条件检查

短期(72小时)

  • 添加 API Token 认证
  • 无条件 UPDATE/DELETE 拒绝执行
  • 错误信息脱敏

中期

  • 表级权限控制(日志表只写不删/改)
  • 管理操作审计日志
  • 日志清理防篡改(保留清理前的摘要/签名)

代码验证记录

验证日期: 2026-08-03
验证方式: 逐条对照审计报告与当前代码(dbv2.py、db_tools.py、example_log_client.py、_view_db.sqlite3.py)

验证结果汇总

等级 总数 已修复 部分修复 未修复 修复率
P0 1 0 1 0 50% (部分)
P1 3 0 1 2 17% (部分)
P2 2 1 0 1 50%
合计 6 1 2 3 33%

逐条验证

编号 状态 代码位置 验证说明
P0-1 ⚠️ 部分 dbv2.py L180, L323-406 已绑定 127.0.0.1;但无认证、SELECT 无默认 LIMIT、UPDATE/DELETE 不强制 WHERE
P1-1 ⚠️ 部分 db_tools.py L166-169, _view_db.sqlite3.py L53 db_tools.py 使用参数化查询;_view_db.sqlite3.py 支持自由 SQL(本地工具)
P1-2 ❌ 未修复 dbv2.py L323-344 _handle_execute 无任何审计日志记录
P1-3 ❌ 未修复 dbv2.py L493-528 _do_cleanup 按时间/条数清理,可被攻击者利用
P2-1 ✅ 已修复 dbv2.py L65-69 retention_days/max_records/cleanup_interval 通过 confs 可配置
P2-2 ❌ 未修复 dbv2.py L262-265, L332 错误信息暴露列名和表名

新增安全措施(审计报告未覆盖)

措施 代码位置 说明
配置白名单校验 dbv2.py L73-81 _merge_ini 仅覆盖已知 section/key,防止意外字段注入
配置完整性校验 dbv2.py L118-129 启动时检查所有必需配置项,缺失则退出
SQLite PRAGMA 优化 dbv2.py L139-155 WAL + NORMAL 同步 + busy_timeout + mmap
表反射线程安全 dbv2.py L225-239 double-check 锁机制防止并发反射竞态
日志队列上限 example_log_client.py L41 _QUEUE_MAXSIZE = 10000,满则丢弃最旧条目
后台线程异常安全网 example_log_client.py L188-192 最外层 catch 防止异常杀死日志线程