diff --git a/db2/src/db2.cpp b/db2/src/db2.cpp index 082b3ed..3b99aa2 100644 --- a/db2/src/db2.cpp +++ b/db2/src/db2.cpp @@ -151,6 +151,25 @@ static Config load_config(int argc, char* argv[]) { // 3. 解析 INI(白名单字段) IniMap ini = parse_ini(ini_text); + + // 校验必需配置项(confs 提供的 db.ini 必须包含完整配置) + static const std::pair required_keys[] = { + {"server", "host"}, + {"server", "port"}, + {"server", "workers"}, + {"database", "url"}, + {"logs", "retention_days"}, + {"logs", "max_records"}, + {"logs", "cleanup_interval"}, + }; + for (auto& [sec, key] : required_keys) { + auto si = ini.find(sec); + if (si == ini.end() || si->second.find(key) == si->second.end()) { + std::fprintf(stderr, "[db2] missing required config: [%s] %s\n", sec, key); + std::exit(1); + } + } + auto get = [&](const std::string& sec, const std::string& key, const std::string& def = "") -> std::string { auto si = ini.find(sec); @@ -790,7 +809,7 @@ private: // 1. 删除超过 retention_days 的记录 std::string cutoff_sql = - "DELETE FROM Logs WHERE ts < datetime('now', '-" + "DELETE FROM Logs WHERE ts < strftime('%Y-%m-%dT%H:%M:%S','now', '-" + std::to_string(_cfg.retention_days) + " days')"; conn.exec(cutoff_sql); int expired = sqlite3_changes(conn.get()); diff --git a/docs/security/db2_SECURITY_AUDIT_20260806.md b/docs/security/db2_SECURITY_AUDIT_20260806.md index 9284fba..649baae 100644 --- a/docs/security/db2_SECURITY_AUDIT_20260806.md +++ b/docs/security/db2_SECURITY_AUDIT_20260806.md @@ -13,9 +13,9 @@ |--------|------|--------|--------| | P0 | 2 | 2 | 0 | | P1 | 1 | 1 | 0 | -| P2 | 2 | 0 | 2 | +| P2 | 2 | 2 | 0 | | P3 | 4 | 1 | 3 | -| **合计** | **9** | **4** | **5** | +| **合计** | **9** | **6** | **3** | --- @@ -88,8 +88,10 @@ ### P2-1: 清理时间戳格式不一致(T vs 空格)导致保留期偏移约 1 天 - **位置**: `db2.cpp` L54-60(`utc_now`)、L787-789(`_do_cleanup`) -- **当前状态**: ❌ 未修复 -- **详情**: +- **当前状态**: ✅ 已修复(2026-08-07) +- **修复**: 清理 SQL 改用 `strftime('%Y-%m-%dT%H:%M:%S','now','-N days')`,与 `utc_now()` 的 `T` 分隔格式完全对齐,截止时间字符串比较正确,保留期精确匹配配置天数。 + +- **原始问题**: 存储的时间戳用 `utc_now()`,格式 `%Y-%m-%dT%H:%M:%S`(T 分隔)。清理 SQL 用 SQLite 内置 `datetime('now', '-N days')`,格式 `%Y-%m-%d %H:%M:%S`(空格分隔): @@ -108,8 +110,10 @@ ### P2-2: 缺少配置完整性校验 - **位置**: `db2.cpp` L131-185(`load_config`) -- **当前状态**: ❌ 未修复 -- **详情**: +- **当前状态**: ✅ 已修复(2026-08-07) +- **修复**: 在 INI 解析后、环境变量覆盖前,对 7 个必需字段(`[server] host/port/workers`、`[database] url`、`[logs] retention_days/max_records/cleanup_interval`)做必填校验,缺失任一则 `fprintf` 明确错误信息后 `exit(1)`,不再用错误默认值静默运行。 + +- **原始问题**: `load_config` 对缺失配置项直接用内置默认值兜底(`get(sec, key, cfg.xxx)` 模式)。Python 版(`dbv2.py` L118-129)校验所有必需配置项,缺失则退出。 @@ -154,10 +158,10 @@ ### 短期(72小时) - [x] **P1-1**: 按 JSON 类型分别使用 `sqlite3_bind_int64` / `sqlite3_bind_double` / `sqlite3_bind_text` -- [ ] **P2-2**: 配置完整性校验(必需字段缺失则退出) +- [x] **P2-2**: 配置完整性校验(必需字段缺失则退出) ### 中期 -- [ ] **P2-1**: 清理时间戳格式统一为 T 分隔 +- [x] **P2-1**: 清理时间戳格式统一为 T 分隔 - [ ] **P3-3**: limit/offset 负值校验 - [ ] **P3-4**: WHERE 条件数 / IN 数组大小上限