Files
Nexus/standards/line-walk-audit-standard-v2.md
2026-07-08 22:31:31 +08:00

15 KiB
Raw Permalink Blame History

逐行代码走读审计完整规范 v2.0

版本: 2.0 · 2026-05-23
适用: Python 后端 / 前端 / Shell 任意项目,AI 辅助全量逐行审计
来源: audit-line-review.mdc + perfect-implementation.mdc + Nexus Phase 14 实战提炼


核心原则(不可妥协)

逐行走读 ≠ 攻击面抽查。 未满足本规范 DoD 的文件不得标记「已审计」。

完美实现原则(来自 perfect-implementation.mdc):

  • 不允许发现问题后绕过 — 必须根治
  • 不允许静默吞错 — except Exception: pass 须证明合理
  • 不允许留 TODO/FIXME — 当场能修必须当场修
  • 不允许无行号 FINDING — 每条必须 文件:行号
  • 无法完美修复时必须停下,告知用户,确认方案后再动

一、术语

术语 定义
走读 对单文件按行号顺序阅读全部源码,对命中规则做上下文分析
触达 仅 grep / 打开文件,未满足走读 DoD,不算完成
规则命中 §四 规则表在某行产生匹配,计入列表 H
Closure 对一条命中的判定:SAFE(附依据)或 FINDING(附行号+理由)
DoD 单文件完成定义,见 §六
ACCEPTED 已知设计取舍,明确接受并文档化,不修复

二、适用范围

包含 排除
server/**/*.py(所有后端) docs/**(仅做密钥扫描)
web/app/*.{html,js}(前端页面) 第三方 minified JSvendor/
web/agent/**(子机 Agent 图片、字体、.pyc
scripts/**deploy/**tests/** frontend/node_modules/**

三、单文件走读流程(8 步,每步必做)

Step 1  登记:文件路径、语言、总行数 N(wc -l 或工具读取)
Step 2  全文 Read 至 EOF(每段 ≤200 行;末段 offset ≥ N-5,须覆盖末行)
Step 3  规则扫描 → 命中列表 H(§四 规则表)
Step 4  对 H 每条 Read ±15 行上下文 → Closure 表(SAFE 或 FINDING
Step 5  API / WebSocket 文件:写入口表(方法 / 路径 / 鉴权方式)
Step 6  标注外部输入 → sinkSQL / shell / 文件路径 / innerHTML / 出站 HTTP
Step 7  八类归类核对(§七)
Step 8  满足 DoD → 标「逐行完成 ✓」

单会话上限:最多 5 个文件 完成 8 步(防止上下文过长导致漏报)。


四、规则表

4.1 Python 后端

ID 匹配模式(示意) 审查要点
PY-01 f-string + exec / shell / ssh / sysctl / curl / sudo / bash 是否经 shell?整段 key=value 是否安全引用?shlex.quote(f"{k}={v}") vs 仅 quote value
PY-02 subprocess. / create_subprocess_shell / os.system shell=True?命令来源是否可控?
PY-03 exec_ssh_command / conn.run( / asyncssh 远程 shell 拼接?命令是否用户可控?
PY-04 text( / execute( / raw( / 字符串拼 SQL SQL 注入?是否用参数绑定?
PY-05 @router. / @app. / websocket / @app.post 是否有 JWT / API Key 鉴权?PUBLIC 白名单是否过宽?
PY-06 字面量 API_KEY / SECRET_KEY / password = / token = 硬编码凭据?
PY-07 pickle / yaml.load( / eval( / exec( 危险反序列化 / 动态执行
PY-08 API Key == / != 应用 secrets.compare_digest(防时序攻击)
PY-09 except 后直接 pass / return None / logger.xxx 无 re-raise 是否静默吞掉安全异常?静默失败是否可接受?
PY-10 open( + 路径变量 / pathlib.Path( + 用户输入 路径遍历?白名单校验?
PY-11 datetime.now() 不带 timezone.utc / 与 now(utc) 相减 tz-aware vs naive 混用 → TypeError
PY-12 float(x) / int(x) 对外部数据无 try/except 非数字输入 → ValueError → 500
PY-13 {**d1, **some_list, ...} dict 解包 list 不是 mapping → TypeError(常被 gather 静默捕获)
PY-14 redis.incr(k)redis.expire(k, t) 两步分开 非原子:崩溃在中间 → key 无 TTL 永久存在
PY-15 String(N) 列存加密后数据 / 大型字段 加密后长度是否仍 ≤ NRSA 4096 Fernet 后 ~4300 chars
PY-16 command.replace("$VAR", value) 多次循环替换 密码含 $VAR 模式 → 嵌套二次替换
PY-17 shlex.quote(x) 后再包进 f'"{q}.suffix"' 单引号结果被双引号包裹 → 文件名含字面单引号
PY-18 cron field step = int(part[2:])value % step step=0 → ZeroDivisionError
PY-19 logger.info(f"... {settings.REDIS_URL}") / {settings.DATABASE_URL} 连接串含密码 → 日志泄露
PY-20 send_telegram(f"...{e}...") / {result} 等外部通知 DB/Redis 详情泄露到 Telegram/Slack

4.2 前端(HTML / JS

ID 匹配模式 审查要点
FE-01 innerHTML / outerHTML 每个 ${} 是否经 esc() / escAttr()
FE-02 localStorage.setItem + token / key JWT / API Key 存 localStorageCSP 是否有
FE-03 WebSocket + ?token= / ?t= in URL Token 在 URL → 日志 / Referer 泄露
FE-04 fetch( 不经封装函数 是否绕过统一 apiFetch(含鉴权 / CSRF)?
FE-05 onclick="…${ / href="javascript:${ JS 属性注入(XSS
FE-06 <script src="https://cdn. / <link href="https:// 是否有 SRIintegrity)?
FE-07 data-xxx="${ / 后端数据直插 HTML 属性 属性注入?须 escAttr

4.3 Shell / Deploy / SQL / Config

ID 范围 要点
SH-01 *.sh 变量引用是否加 ""、curl 是否含密钥、路径是否变量拼接
DP-01 nginx*.conf CSP 头、TLS 配置、是否暴露 .env
SQL-01 *.sql GRANT ALL'%'(任意主机)、明文密码
CFG-01 .env.example / config.json 是否含真实密钥?

H=0 规则:即使无规则命中,仍须完成 Step 2 全文 Read,Closure 表写明「规则零命中,全文确认 CLEAN」。


五、Closure 表格式

| 文件 | 行号 | 规则 | 判定 | 严重度 | 理由 / 修复建议 |
|------|------|------|------|--------|-----------------|
| sync_engine_v2.py | 243 | PY-01 | FINDING | P2 | config value 含换行符拼入 echo → 多行注入;剥离 \n\r\x00 |
| sync_engine_v2.py | 95 | PY-01 | SAFE | — | rsync 两端路径均 shlex.quote,不经用户可控拼接 |
| agent.py | 69 | PY-08 | SAFE | — | compare_digest(provided, stored) 已使用 |
| auth.py | 116 | PY-09 | ACCEPTED | — | /logout 无 JWT 是设计决策:access token 无状态,仅清 refresh |
  • SAFE:必须写明依据(argv 不经 shell / Pydantic 校验 / 常量输入 / 白名单)
  • FINDING:对应八类 + 行号 + 一行修复建议
  • ACCEPTED:写明接受理由,不得留空

六、单文件 DoD(缺一不可)

[ ] Step 2Read 覆盖 1..N(报告写明 N 与实际 Read 范围)
[ ] Step 4len(H) == Closure 行数(含 SAFE
[ ] Step 5:有 @router / websocket → 有入口表;纯 __init__ 可 N/A
[ ] Step 6:已标注外部输入→sink 或写明「无外部输入」
[ ] Step 7:八类已勾选
[ ] 无「Top 15」「已大体审计」「整体 CLEAN」等笼统结论

七、八类分类与严重度

代号 P0 例 P1 例 P2/P3 例
安全漏洞 VULN 未授权 RCE / IDOR Shell XSS / 命令注入 / 越权 信息泄露 / 会话固定
安全风险 RISK 仓库内生产 API Key 明文 HTTP 传凭据 非原子 rate limit
功能缺陷 BUG 加密列宽不足 → 截断 tz-aware/naive 相减 → TypeError float() 无保护 → 500
外部化缺失 EXT 无全局鉴权中间件 无危险命令拦截 缺日志
规范违规 STYLE 未 esc 的 innerHTML 过宽 public 路径
性能 PERF 心跳每次写 MySQL N+1 查询
可用性 UX 错误无提示静默失败 缺进度状态
优化点 OPT 重复逻辑 / 死代码

KPI 约定P0 漏报 -100P1 漏报 -50(用于 AI 质量评估)。


八、严重度定义

级别 定义 处置
P0 未授权可利用:RCE / IDOR / 仓库密钥 / 任意用户越权 阻塞合并,当场修复
P1 认证后可利用或高影响缺陷:命令注入 / XSS / 凭据泄露 / 关键路径 TypeError 当前批次修复
P2 正确性或安全加固:float 无保护 / tz 混用 / 非原子操作 / 列宽不足 本迭代修复
P3 低风险 / 防御性改进 / 代码整洁 顺手修或记录
📋 ACCEPTED 设计取舍,已知且接受 文档化理由
🟡 PARTIAL 有缓解但未彻底 文档化缓解措施

九、批次规划建议

批次 目录 / 主题 文件数上限
1a 路由层(API handlers 15
1b 业务层(Services 10
1c 基础设施层(DB / Redis / SSH / 外部服务) 20
1d 入口与配置(main / config / background 8
1e 前端页面(HTML / JS 15
1f 子机 / 脚本 / 测试 20
2a 修复后重读(Phase 1 修改行数最多的文件) 10
2b 遗留文件 / 新增文件补充走读 按需

每批结束产出:

  1. 走读报告 docs/reports/audit-phase-Xn-line-walk.md
  2. FINDING 矩阵更新(全量状态表)
  3. 修复 commit 推送

十、全量 FINDING 矩阵格式

维护一张总表:

| ID | 文件:行号 | 类 | 级 | 状态 | 描述 | 修复/备注 |
|----|-----------|----|----|------|------|---------|
| F1a-01 | api/auth.py:45 | VULN | P0 | ✅ | ... | ... |
| F1b-03 | services/sync.py:187 | BUG | P2 | ⏳ | ... | ... |
| F1c-02 | infra/ssh.py:92 | RISK | P1 | 📋 | ... | 网络隔离接受 |

每次修复后更新状态。代码待办 = 0 是合并前硬性要求。


十一、文档纪律(来自 perfect-implementation.mdc

修复流程:发现 FINDING → 当场修复(P0/P1)或记录(P2/P3)→ 写 changelog → commit

每次有意义的修复必须:

文档 路径 必含内容
Changelog docs/changelog/YYYY-MM-DD-<主题>.md 日期 / 变更摘要 / 动机 / 涉及文件 / 验证方式
走读报告 docs/reports/audit-phase-Xn-line-walk.md 文件清单 / Closure 全表 / Findings / 走读签字
FINDING 矩阵 docs/reports/audit-findings-matrix.md 全量状态,持续更新

禁止:把 changelog 只写在 commit message 里代替文档。


十二、禁止行为清单

❌ 无 `文件:行号` 的 FINDING
❌ `rg 命中 ≠ Closure 数` 仍标「完成」
❌ 子代理 Top 15 代替 Closure 全表
❌ 单回复声称整个 server/ 或 web/ 已完成
❌ 逐行审计与修代码混做(除非用户明确要求同步修复)
❌ SAFE 无依据(不写为何 SAFE,等于没做)
❌ FINDING 无修复建议(至少一行说明如何修)
❌ 发现问题留 TODO,不当场修复(来自 perfect-implementation.mdc

十三、常见高频漏报(必须覆盖)

陷阱 典型错误代码 正确做法
shlex 引号混用 f'"{shlex.quote(path)}.pid"' f'{shlex.quote(path)}.pid'(单引号直接用)
tz 混用 naive_dt - datetime.now(utc) 比较前统一:naive.replace(tzinfo=None) 或全用 utc
list ** 解包 {**d, **some_list} {"key": some_list}
非原子 rate limit incr(k); expire(k, t) pipeline: incr + expire 或 Lua 脚本
DB 列宽 String(500) 存加密 SSH 私钥 TextRSA 4096 Fernet 后 ~4300 chars
变量替换嵌套 cmd.replace("$PASS", pw) + pw 含 $USER 先全部替换为 sentinel,再用真值替换 sentinel
cron 除零 value % step 未判 step==0 if step == 0: return False
日志泄密 logger.info(settings.DATABASE_URL) 脱敏后再 log(仅显示 host:port
命令已执行再检测 shell.stdin.write(cmd) → check_dangerous(cmd) 顺序错误;WebSSH 层无法阻断,只能记录
gather 吞异常 gather(*tasks, return_exceptions=True) 未检查结果 遍历结果,对 isinstance(r, Exception) 单独处理

十四、给 AI 的执行提示词

14.1 开始走读(粘贴给 AI

请按以下规范对 [文件/目录] 进行逐行代码走读审计:

【规范】
1. 单文件 8 步:登记行数 → 全文 Read 至 EOF → 规则扫描 → Closure 表 → 入口表 → 输入→sink → 八类核对 → DoD
2. 每段 Read ≤200 行;末段须覆盖末行(offset ≥ N-5)
3. 规则命中列表 H:对每条 Read ±15 行上下文
4. Closure 表每行必须有:文件 | 行号 | 规则 | SAFE/FINDING | 严重度 | 理由
5. FINDING 格式:ID | 文件:行号 | 类型(VULN/BUG/RISK...) | P0/P1/P2/P3 | 描述 | 修复建议
6. H=0 仍须全文 Read,Closure 表注明「规则零命中,全文 CLEAN」
7. 单回复最多 5 个文件完成 8 步

【禁止】
- 无行号的 FINDING
- 仅 grep 不全文 Read 就标「已审计」
- 声称整个目录一次完成

【重点规则】(必检)
- PY-01: f-string 命令拼接
- PY-08: API Key == 比较(应用 compare_digest
- PY-09: except 静默
- PY-11: tz-aware/naive 混用
- PY-14: redis INCR+EXPIRE 非原子
- PY-15: String(N) 列宽不足
- FE-01: innerHTML 未 esc

【产出】
- Closure 全表(含 SAFE
- FINDING 列表(含行号)
- 入口表(API 文件)
- 走读签字:文件 | N | H 数 | FINDING 数

14.2 修复验证

以下 FINDING 已修复,请验证修复是否完整:

FINDING: [ID] [文件:行号] [描述]
修复前:
[原代码]
修复后:
[新代码]

请确认:
1. 修复是否覆盖了原始问题
2. 修复是否引入新问题
3. 是否有边界情况遗漏
4. 若确认正确,将状态更新为 ✅

14.3 闭环声明生成

请根据以下走读记录生成 Phase X 走读闭环声明:

覆盖批次:[Xa, Xb, ...]
FINDING 矩阵:[附表]

闭环声明必须包含:
1. 覆盖范围(批次 + 文件列表 + 大约行数)
2. FINDING 统计(总数 / ✅已修复 / 📋接受 / 🟡部分 / ⏳待修)
3. CLEAN 文件列表(附简要理由)
4. 代码待办数(目标 = 0)
5. 遗留观察(不修复的设计说明)
6. 签字:Phase X 走读已闭环,可进入 [下一阶段]

十五、闭环声明模板

# Phase X 走读闭环声明

**日期**: YYYY-MM-DD
**标准**: 本规范 v2.0

## 覆盖范围
| 批次 | 目录 | 文件数 | 总行数 |
...

## FINDING 统计
- 总计: N 条
- ✅ 已修复: N
- 📋 接受: N
- 🟡 部分缓解: N
- ⏳ 代码待办: **0**(合并前硬性要求)

## CLEAN 文件(无 FINDING
- `file1.py` — 鉴权正确,命令均 shlex.quote,无外部输入 sink
- ...

## 遗留观察(不修复)
- 子机 shell 执行面(F1f-01):📋 架构接受,网络隔离 + 审计日志

## 签字
Phase X 走读已闭环。代码待办 0。可进入 [首次部署 / 下一功能迭代]。

本规范完全通用,可直接粘贴给任何 AI 执行逐行走读任务。路径、批次编号按实际项目调整。