逐模块对照实际代码验证审计报告中的问题修复状态,添加代码验证记录、逐条验证结果、修复率统计。合并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%
129 lines
6.6 KiB
Markdown
129 lines
6.6 KiB
Markdown
# 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 防止异常杀死日志线程 |
|