Files
blackbird/docs/security/pymsg_SECURITY_AUDIT_20260801.md
qing 373045f0a3 pymsg: 将已修复安全审计项合入源码注释, 精简审计报告
- 将 P0-1/P0-2/P1-1/P1-2/P1-3/P1-5 共 6 条已修复发现作为
  [SECURITY AUDIT ... ✅ 已修复] 注释合入 pymsg 源码对应位置
- 重写 pymsg 审计报告, 删除已合并条目, 仅保留 10 条未修复项待跟踪
2026-08-10 01:08:55 +08:00

146 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# pymsg 模块安全审计报告
**审计日期**: 2026-08-01
**审计范围**: `pymsg/__init__.py`、`pymsg/rpc.py`、`pymsg/async_queue.py`
**代码版本**: dev_qing 分支
---
## ⚠️ 合并追溯说明(2026-08-10)
原始审计报告共 16 条发现(P0×3 / P1×5 / P2×4 / P3×4)。其中 **6 条已修复项**
(P0-1、P0-2、P1-1、P1-2、P1-3、P1-5)的修复代码已落地并经 2026-08-03 验证,
现已作为 `[SECURITY AUDIT ... ✅ 已修复]` 注释合并进源文件对应位置:
| 编号 | 已合并位置 |
|------|------------|
| P0-1 | `pymsg/__init__.py` — `recv()`、`_recv_exact()` |
| P0-2 | `pymsg/__init__.py` — `recv()`、`_handle_client()` |
| P1-1 | `pymsg/__init__.py` — `MsgServer.__init__`、`_accept_client()` |
| P1-2 | `pymsg/__init__.py` — `_BoundedThreadPoolExecutor` 类、`MsgServer.__init__`、`_handle_client()` |
| P1-3 | `pymsg/rpc.py` — `_sanitize_error()` |
| P1-5 | `pymsg/rpc.py` — 模块顶部 `_MAX_NUM_DIGITS` 注释、`_dispatch()` |
**本报告以下章节仅保留尚未修复(未合并)的 10 条发现作为待办跟踪**,已修复条目
已从「逐条验证」「修复进度」及详细问题章节中删除,其完整描述见源代码注释。
---
## 剩余未修复条目(待跟踪)
### 汇总
| 等级 | 剩余总数 | 说明 |
|------|----------|------|
| P0 | 1 | 无认证/鉴权机制 |
| P1 | 1 | 明文 TCP,无 TLS |
| P2 | 4 | 健壮性/配置问题 |
| P3 | 4 | 优化建议 |
| **合计** | **10** | |
### 逐条验证(仅未合并项)
| 编号 | 状态 | 代码位置 | 说明 |
|------|------|----------|------|
| P0-3 | ❌ 未修复 | `rpc.py` L80-171 | 无认证机制,仅依赖 127.0.0.1 网络层隔离 |
| P1-4 | ❌ 未修复 | 全模块 | 明文 TCP,无 TLS 支持 |
| P2-1 | ❌ 未修复 | `__init__.py` L106-111 | length=0 空消息无特殊处理 |
| P2-2 | ❌ 未修复 | `__init__.py` L395-418 | `broadcast()` 无频率/权限控制 |
| P2-3 | ❌ 未修复 | `__init__.py` L377-378 | `except (ValueError, OSError): break` 仍捕获所有 OSError(含 EINTR) |
| P2-4 | ❌ 未修复 | `__init__.py` L196-203 | `MsgClient.send()` 短连接模式,高频调用导致 TIME_WAIT 堆积 |
| P3-1 | ❌ 未修复 | - | 安全事件(超大消息、超时、JSON 解析失败)无日志 |
| P3-2 | ❌ 未修复 | `__init__.py` L182 | `name` 参数未过滤控制字符 |
| P3-3 | ❌ 未修复 | `__init__.py` L359 | `listen(10)` backlog 在高并发下偏小 |
| P3-4 | ❌ 未修复 | `__init__.py` L520-527 | `_shutdown` 直接 `close()` 所有 socket,可能发送 RST |
---
## 问题严重等级
| 等级 | 说明 | 响应时间 |
|------|------|----------|
| P0 🔴 | 可导致服务崩溃、DoS 或远程接管 | 立即修复 |
| P1 🟠 | 可导致资源耗尽、信息泄露 | 72小时内 |
| P2 🟡 | 健壮性/配置问题 | 一周内 |
| P3 🟢 | 优化建议 | 版本迭代 |
---
## 修复进度(剩余)
| 优先级 | 剩余待修复 |
|--------|------------|
| P0 | 1(无认证) |
| P1 | 1(无 TLS) |
| P2 | 4 |
| P3 | 4 |
---
## 🔴 P0 — 严重问题
### P0-3: 无认证/鉴权机制
- **位置**: `rpc.py:80-171` 整个 RpcServer
- **问题**: RPC 服务完全没有身份验证,任何能连接到端口的客户端都能调用所有路由
- **当前缓解**: 所有服务均绑定 127.0.0.1,依赖网络层隔离
- **修复建议**:
1. 添加基于预共享 token 的认证(如 `_auth` 字段)
2. 支持路由级权限控制
3. 文档明确警告不要暴露到公网
---
## 🟠 P1 — 高危问题
| # | 问题 | 位置 | 状态 |
|---|------|------|------|
| P1-4 | 无 TLS/加密传输,内网流量可被窃听 | 全模块明文 TCP | ❌ 未修复 |
---
## 🟡 P2 — 中危问题
| # | 问题 |
|---|------|
| P2-1 | length=0 空消息未特殊处理,可用于心跳攻击 |
| P2-2 | broadcast() 无频率/权限控制,可被用于放大攻击 |
| P2-3 | select 异常处理过于宽泛,EINTR 临时错误直接退出循环 |
| P2-4 | MsgClient 短连接模式导致 TIME_WAIT 堆积 |
---
## 🟢 P3 — 低危/建议
| # | 建议 |
|---|------|
| P3-1 | 安全事件(超大消息、超时、JSON解析失败)无日志 |
| P3-2 | `name` 参数未过滤控制字符,可导致日志注入 |
| P3-3 | listen backlog=10 在高并发下偏小 |
| P3-4 | 无优雅关闭(直接 close() 可能发送 RST) |
---
## ✅ 已有安全机制
1. ✅ 64 MiB 消息大小上限(`_MAX_MSG_SIZE`),防止 OOM
2. ✅ send/recv 双端都检查消息大小
3. ✅ 线程池模式下同一连接串行处理,避免帧交错
4. ✅ 使用 `sendmsg` 散射-聚集 I/O 减少内存拷贝
5. ✅ 使用 `recv_into` 预分配 buffer
6. ✅ 线程安全的发送锁
7. ✅ 回调异常隔离(线程池模式)
8. ✅ 单元测试覆盖消息大小边界
> 注:P0-1(recv 总超时)、P0-2(UnicodeDecodeError 防护)、P1-1(连接数限制)、
> P1-2(有界队列)、P1-3(异常脱敏)、P1-5(JSON 解析限制)等已修复机制均已合并进
> 源代码注释,见开头「合并追溯说明」。
---
## 修复路线图(剩余)
### 中期
- [ ] 统一认证机制(P0-3)
- [ ] TLS 支持选项(P1-4)
- [ ] 安全事件日志(P3-1)