123 lines
3.8 KiB
Markdown
123 lines
3.8 KiB
Markdown
# 逐行审计核心原则
|
||
|
||
> **适用**:所有代码审计任务,AI 执行前必读
|
||
> **地位**:不可妥协的底线;具体流程见 `line-walk-audit-standard-v2.md`
|
||
|
||
---
|
||
|
||
## 一、审计本质
|
||
|
||
**逐行走读 ≠ 攻击面抽查。**
|
||
|
||
| 逐行走读 ✅ | 攻击面抽查 ❌(不算审计)|
|
||
|-----------|---------------------|
|
||
| 全文 Read 至 EOF | 只 grep 关键词 |
|
||
| 对每条命中做上下文分析 | 列 Top 15 不给行号 |
|
||
| 每条 SAFE 写明依据 | 笼统说「整体 CLEAN」|
|
||
| 单回复 ≤5 个文件 | 声称单回复完成整个目录 |
|
||
|
||
---
|
||
|
||
## 二、实现原则(不可妥协)
|
||
|
||
```
|
||
❌ 不允许绕过 — 发现问题必须根治,不得用静默/硬编码/注释掩盖
|
||
❌ 不允许降级 — 不得以「先用着」「以后再改」推迟安全修复
|
||
❌ 不允许留债 — 不得留 TODO / FIXME 延后处理,当场能修必须当场修
|
||
❌ 不允许无依据 — SAFE 结论必须写明为何 SAFE,空结论等于没做
|
||
❌ 不允许无行号 — 每条 FINDING 必须 `文件:行号`,无行号无效
|
||
✅ 无法完美修复时 — 停下告知用户,确认方案后再动;不擅自从权
|
||
```
|
||
|
||
---
|
||
|
||
## 三、走读质量底线(DoD)
|
||
|
||
完成一个文件,必须同时满足:
|
||
|
||
```
|
||
[ ] 全文 Read 覆盖第 1 行 ~ 第 N 行(N = 总行数)
|
||
[ ] 规则命中数 H == Closure 表行数(含 SAFE 和 FINDING)
|
||
[ ] 每条 FINDING:文件:行号 + 类型 + 严重度 + 修复建议
|
||
[ ] 每条 SAFE:写明依据(argv / 白名单 / 常量 / 校验函数)
|
||
[ ] 有 API/WebSocket 路由:必须有入口表(路径 + 鉴权方式)
|
||
[ ] 标注外部输入 → sink,或写明「无外部输入」
|
||
```
|
||
|
||
---
|
||
|
||
## 四、严重度与处置
|
||
|
||
| 级别 | 定义 | 处置 |
|
||
|------|------|------|
|
||
| **P0** | 未授权可利用:RCE / IDOR / 仓库密钥 | **阻塞,当场修复** |
|
||
| **P1** | 认证后利用 / 高影响缺陷:注入 / XSS / 关键 TypeError | 当前批次修复 |
|
||
| **P2** | 正确性 / 安全加固:float无保护 / tz混用 / 非原子 | 本迭代修复 |
|
||
| **P3** | 防御性改进 / 代码整洁 | 顺手修或记录 |
|
||
| **📋** | 已知设计取舍,明确接受 | 文档化理由,不修复 |
|
||
|
||
**代码待办 = 0 是合并前硬性要求。**
|
||
|
||
---
|
||
|
||
## 五、修复纪律
|
||
|
||
每次修复必须:
|
||
|
||
1. **当场写 changelog** — `docs/changelog/YYYY-MM-DD-<主题>.md`
|
||
2. **更新 FINDING 矩阵** — 将状态改为 ✅,附 commit hash
|
||
3. **commit 推送** — 修复单独 commit,不与无关改动混提
|
||
|
||
禁止:把 changelog 只写进 commit message 代替文档。
|
||
|
||
---
|
||
|
||
## 六、KPI 约定
|
||
|
||
```
|
||
P0 漏报:-100 分
|
||
P1 漏报:-50 分
|
||
无行号 FINDING:不计入有效 FINDING
|
||
SAFE 无依据:该条 Closure 不计入完成
|
||
```
|
||
|
||
---
|
||
|
||
## 七、最常漏报的 10 个模式
|
||
|
||
```python
|
||
# ❌ 1. tz 混用
|
||
now(utc) - mysql_naive_datetime # TypeError
|
||
|
||
# ❌ 2. shlex+双引号混用
|
||
f'"{shlex.quote(path)}.pid"' # 单引号被当字面量
|
||
|
||
# ❌ 3. list ** 解包
|
||
{**d1, **some_list, "k": v} # TypeError(gather 静默捕获)
|
||
|
||
# ❌ 4. 非原子 rate limit
|
||
redis.incr(k); redis.expire(k, t) # 崩溃 → key 无 TTL 永久存在
|
||
|
||
# ❌ 5. 替换嵌套
|
||
cmd.replace("$PASS", password) # password 含 $USER → 二次替换
|
||
|
||
# ❌ 6. DB 列宽
|
||
String(500) 存 Fernet 加密 RSA 4096 私钥 # ~4300 chars → DataError
|
||
|
||
# ❌ 7. cron 除零
|
||
value % step # step=0 未判断 → ZeroDivisionError
|
||
|
||
# ❌ 8. 日志泄密
|
||
logger.info(f"Redis: {settings.REDIS_URL}") # URL 含密码
|
||
|
||
# ❌ 9. 命令已发再检测
|
||
shell.stdin.write(data); check_dangerous(cmd) # 顺序反了,命令已执行
|
||
|
||
# ❌ 10. gather 吞异常
|
||
await gather(*tasks, return_exceptions=True) # 未遍历结果检查 Exception
|
||
```
|
||
|
||
---
|
||
|
||
*单独使用:将本文件内容贴给 AI 作为系统提示词前缀,再附上具体走读任务。*
|