euthyna 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/euthyna/SKILL.md +256 -0
- package/.agents/skills/euthyna/references/bug-classes.md +130 -0
- package/.agents/skills/euthyna/references/change-audit.md +219 -0
- package/.agents/skills/euthyna/references/dependency-audit.md +116 -0
- package/.agents/skills/euthyna/references/fact-contract.md +129 -0
- package/.agents/skills/euthyna/references/fact-producers.md +274 -0
- package/.agents/skills/euthyna/references/meta-mechanisms.md +173 -0
- package/.agents/skills/euthyna/references/verification-gates.md +293 -0
- package/LICENSE +202 -202
- package/README.md +65 -17
- package/cordis.patch.yml +4 -0
- package/package.json +23 -3
- package/plugin/index.js +60 -0
- package/src/cli.js +157 -6
- package/src/contract.js +2 -1
- package/src/facts/coverage.js +55 -2
- package/src/facts/deps.js +366 -0
- package/src/facts/history.js +322 -25
- package/src/gate.js +381 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# 元机制:让流程真正生效的六件事
|
|
2
|
+
|
|
3
|
+
> 阶段 A / B / C 是**流程**。这份文件是让流程不至于退化成走过场的**机制**。
|
|
4
|
+
>
|
|
5
|
+
> 它们的共同点是:**都不靠自觉**。凡是靠「记住要仔细」的约束,在长会话里都会失效。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 一、防「算错数」:测量与判断分离
|
|
10
|
+
|
|
11
|
+
**规则**:凡是可测量的量,一律由命令或脚本产出。模型只做判读。
|
|
12
|
+
|
|
13
|
+
调用方数量、测试覆盖率、依赖版本、行号、提交哈希、函数被调用几次——
|
|
14
|
+
**这些一律不许靠印象回答**。工具不可用时说「不可测量」,**不许估算后当成事实写进结论**。
|
|
15
|
+
|
|
16
|
+
### 为什么这条必须硬化
|
|
17
|
+
|
|
18
|
+
模型估算这类数字不是「不太准」,而是**系统性错误**,并且错得让人察觉不到:
|
|
19
|
+
|
|
20
|
+
- 某个包在代码托管平台上显示 5+ 人维护,而它在包管理器里的实际权限列表只有 **1 人**
|
|
21
|
+
- 一个每周下载 1.6 亿次的包,在某个数据源里显示**零下载**
|
|
22
|
+
|
|
23
|
+
这两个都是实测翻车案例。它们说明的不是「要更小心」,而是
|
|
24
|
+
**手感估数字这件事本身不可靠,无论怎么努力**。
|
|
25
|
+
|
|
26
|
+
### 落地
|
|
27
|
+
|
|
28
|
+
本项目为此提供了产出器,并定义了契约(`fact-contract.md`):
|
|
29
|
+
|
|
30
|
+
```powershell
|
|
31
|
+
# <euthyna 仓库> = 本项目检出的位置,不是被审计项目的路径
|
|
32
|
+
node <euthyna 仓库>/bin/euthyna.js history --base <rev> --repo <被审计的仓库>
|
|
33
|
+
node <euthyna 仓库>/bin/euthyna.js coverage --coverage <file> --symbol <name>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
⚠️ 写成相对的 `node bin/euthyna.js` 会失败:审计时当前目录是被审计的项目。
|
|
37
|
+
命令、退出码与失效情形见 `fact-producers.md`。
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 二、防「报假货」:证据强制 + 门槛二分
|
|
42
|
+
|
|
43
|
+
### 2.1 证据强制到 `file:line`
|
|
44
|
+
|
|
45
|
+
- 每条主张引用具体位置:`path:L123`,有版本时写 `path:L123 (commit abc1234)`
|
|
46
|
+
- 禁用 `probably` / `likely` / `大概是`——去追真实代码,追不了就**明说追不了**
|
|
47
|
+
- 演示代码里禁止 `TODO`、`...`、`// 攻击者在这里做某事`
|
|
48
|
+
- **一旦发现演示用了人为绕过**(mock、stub、禁用检查),该演示判定**无效**
|
|
49
|
+
|
|
50
|
+
### 2.2 「抬高门槛」不等于「消除缺陷」
|
|
51
|
+
|
|
52
|
+
这是最容易混淆、也最容易导致高估严重性的一处。防护要分两类:
|
|
53
|
+
|
|
54
|
+
| 类别 | 例子 | 意义 |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| **彻底阻止** | Rust 安全类型系统对内存破坏;参数化查询对 SQL 注入 | 该类缺陷不可能发生 |
|
|
57
|
+
| **只抬高门槛** | ASLR、栈金丝雀、CFI | 更难,但**没有消除** |
|
|
58
|
+
|
|
59
|
+
同理要分清:
|
|
60
|
+
|
|
61
|
+
- **主要安全控制** vs **纵深防御**——主要防护完好时,纵深防御失效**不算缺陷**
|
|
62
|
+
- **数学上不可能** / **实践中不可行** / **可行**——三态必须说清,不能混为一谈
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 三、防「漏真货」:双向怀疑 + 三态诚实
|
|
67
|
+
|
|
68
|
+
只防误报的系统会退化成「什么都说不是」——那和「什么都说有」一样没用。
|
|
69
|
+
|
|
70
|
+
### 3.1 恶魔代言人必须双向
|
|
71
|
+
|
|
72
|
+
反对缺陷的问题(防误报)之外,**必须**问这两条:
|
|
73
|
+
|
|
74
|
+
> **12. 我是否因为利用方式复杂或不太可能,就否定了一个真实的缺陷?**
|
|
75
|
+
> **13. 我是否编造了未在源码中验证的缓解措施或校验逻辑?**(得出结论后**重读代码**)
|
|
76
|
+
|
|
77
|
+
第 12、13 问**任何情况下都要问**。模型的默认偏差是「报太多」,所以大多数机制都在压制它;
|
|
78
|
+
**压制过头就会漏掉真漏洞**,这两问是对称的配重。
|
|
79
|
+
|
|
80
|
+
### 3.2 三态,不是两态
|
|
81
|
+
|
|
82
|
+
每个判据只能落到:**已评估-干净 / 已评估-标记 / 因某原因不可评估**。
|
|
83
|
+
|
|
84
|
+
- 一次什么都没测到的运行,产出的是「不可评估」,**不是**「没发现问题」
|
|
85
|
+
- 引用任何「干净」结论之前,先看覆盖表
|
|
86
|
+
- **数字必须逐字引用**,不得重新推导、四舍五入或修饰
|
|
87
|
+
- **没发现不等于背书**
|
|
88
|
+
|
|
89
|
+
### 3.3 裁定要有第三态
|
|
90
|
+
|
|
91
|
+
只有「真 / 假」两态时,「没查完」会被迫写成「假」——那是在制造假阴性。
|
|
92
|
+
|
|
93
|
+
所以裁定必须有 `INCONCLUSIVE`,且**必须写明缺什么、为什么缺**。
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 四、防「偷懒」:预先列举借口
|
|
98
|
+
|
|
99
|
+
**「要仔细」没有用。有用的是预先列出模型在实际审计中会产生的偷懒念头,逐条封死。**
|
|
100
|
+
|
|
101
|
+
| 借口 | 为什么错 | 必须做什么 |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| 改动很小,快速看一下 | 最严重的历史漏洞可能只有两行 | 按**风险**分类,不按规模 |
|
|
104
|
+
| 这个代码库我熟 | 熟悉产生盲区 | 显式建立基线 |
|
|
105
|
+
| 翻 git 历史太费时间 | 历史揭示回归 | **不许跳过**来源归属 |
|
|
106
|
+
| 影响面一眼就能看出来 | 会漏掉传递调用者 | 定量计算 |
|
|
107
|
+
| 没有测试不是我的问题 | 缺测试 = 风险升级 | 写进报告并**提升**严重性 |
|
|
108
|
+
| 只是重构,没有安全影响 | 重构会破坏不变量 | 在**证明**为低风险之前一律按高风险分析 |
|
|
109
|
+
| 我口头说明就行 | 没有产物 = 发现丢失 | 必须写报告文件 |
|
|
110
|
+
| 这个模式看着危险 | 模式识别不是分析 | 完成数据流追踪才能下结论 |
|
|
111
|
+
| 相似的代码在别处是漏洞 | 每处的上下文、调用方、防护都不同 | 独立验证本实例 |
|
|
112
|
+
| 这明显是严重漏洞 | 模型偏向于看到 bug 并高估严重性 | 完成恶魔代言人复核,用证据证明 |
|
|
113
|
+
| 跳过完整验证以省时间 | 不允许部分分析 | 按选定路径执行**全部**步骤 |
|
|
114
|
+
|
|
115
|
+
**这张表要在每次审计开始时显式加载**,而且**要跟着真实事故增长**——
|
|
116
|
+
每发现一次新的偷懒模式就补一行。它是一份活的清单。
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 五、防「丢失」:输出必须落盘
|
|
121
|
+
|
|
122
|
+
- **只输出到聊天算失败**。必须写报告文件
|
|
123
|
+
- 写文件失败时的降级顺序:当前工作目录 → 桌面 → 临时目录 → **最后手段**才输出到聊天并提示手动保存
|
|
124
|
+
- 文件名带项目名与日期
|
|
125
|
+
|
|
126
|
+
设计意图:聊天记录会滚走、会被压缩,**文件不会**。一份交付物的存续不该依赖会话的长度。
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 六、防「污染」:能力按阶段隔离
|
|
131
|
+
|
|
132
|
+
### 6.1 门禁不可委派
|
|
133
|
+
|
|
134
|
+
有些阶段需要**跨阶段的综合判断**,把它们交给子代理等于把责任切碎:
|
|
135
|
+
|
|
136
|
+
- 影响评估
|
|
137
|
+
- 恶魔代言人复核
|
|
138
|
+
- 门禁裁定
|
|
139
|
+
|
|
140
|
+
**这三项不得委派。**
|
|
141
|
+
|
|
142
|
+
### 6.2 子代理权限刻意不对称
|
|
143
|
+
|
|
144
|
+
| 角色 | 权限 |
|
|
145
|
+
|---|---|
|
|
146
|
+
| 数据流分析 | **只读** |
|
|
147
|
+
| 可利用性验证 | **只读** |
|
|
148
|
+
| 演示构建 | 唯一可写 |
|
|
149
|
+
|
|
150
|
+
理由:**制造证据的能力只集中在一个阶段**。前置阶段只能观察——
|
|
151
|
+
如果分析阶段就能写文件,它就能「顺便」把证据改成支持自己结论的样子。
|
|
152
|
+
|
|
153
|
+
### 6.3 依赖未完成,绝不开始下一阶段
|
|
154
|
+
|
|
155
|
+
任务开始时标 in-progress,**只有具体证据才能标 completed**。
|
|
156
|
+
并行子阶段并发启动,进入下一依赖门禁前**收齐所有结果**。
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## 这六条之间的关系
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
一、测量与判断分离 ─┐
|
|
164
|
+
├─→ 让「事实」可信
|
|
165
|
+
二、证据强制 ──────┘
|
|
166
|
+
├─→ 让「结论」可信
|
|
167
|
+
三、双向怀疑 ──────┘
|
|
168
|
+
四、借口表 ───────────→ 让流程不被绕过
|
|
169
|
+
五、落盘 ─────────────→ 让产出存续
|
|
170
|
+
六、能力隔离 ─────────→ 让流程不被污染
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
前三条决定**结论质量**,后三条决定**流程质量**。缺任何一条,整套东西都会在某个环节退化。
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# 阶段 C:结论面验证(判定层)
|
|
2
|
+
|
|
3
|
+
> **定位**:不找 bug,只判定已有疑似 bug 的真假。
|
|
4
|
+
> 触发语是「这是真的吗」「验证这个发现」「是否可利用」。
|
|
5
|
+
>
|
|
6
|
+
> 本文件是 euthyna 的核心资产。测量层谁都能做,**判定纪律才是差异点**。
|
|
7
|
+
> 方法论来源与许可见 `NOTICE.md`。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## C.0 第零步:重述断言(不可跳过)
|
|
12
|
+
|
|
13
|
+
用自己的话重述,逐项写下来。**不许直接进入分析。**
|
|
14
|
+
|
|
15
|
+
| 要重述的 | 说明 |
|
|
16
|
+
|---|---|
|
|
17
|
+
| 确切漏洞主张 | 一句话,可判真假 |
|
|
18
|
+
| 声称的根因 | 缺陷在**哪里**、**为什么** |
|
|
19
|
+
| 声称的触发方式 | 攻击者做什么 |
|
|
20
|
+
| 声称的影响 | 落到 RCE / 提权 / 信息泄露 |
|
|
21
|
+
| **威胁模型** | 代码以什么权限运行?是否沙箱?攻击者触发前已经能做什么? |
|
|
22
|
+
| 缺陷类别 | 9 类之一(见 `bug-classes.md`) |
|
|
23
|
+
| 执行上下文 | 单线程?有同步?生命周期? |
|
|
24
|
+
| 调用者分析 | 谁调用它、以什么参数 |
|
|
25
|
+
| 架构上下文 | 它在系统里处于什么位置 |
|
|
26
|
+
| 历史上下文 | 这段代码是何时、为何加进来的 |
|
|
27
|
+
|
|
28
|
+
> **一半的误报在这一步就崩塌了**——当断言被精确重述时,它根本讲不通。
|
|
29
|
+
> 所以这一条不是形式主义:它是性价比最高的过滤器。
|
|
30
|
+
|
|
31
|
+
**产出**:把重述结果写成事实契约里的 `subject.claim`(见 `docs/fact-contract-zh.md`)。
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## C.1 路由:标准验证 vs 深验证
|
|
36
|
+
|
|
37
|
+
### 走标准验证(线性单遍清单)——需**全部**满足
|
|
38
|
+
|
|
39
|
+
- 断言清晰具体
|
|
40
|
+
- 单组件(无跨组件交互)
|
|
41
|
+
- 缺陷类别已知
|
|
42
|
+
- 无并发或异步
|
|
43
|
+
- 数据流直白
|
|
44
|
+
|
|
45
|
+
### 走深验证(任务化编排 + 子代理)——**任一**满足即走
|
|
46
|
+
|
|
47
|
+
- 断言含糊、可有多种解读
|
|
48
|
+
- 跨组件(数据流经 3 个以上模块)
|
|
49
|
+
- 涉及竞争条件或 TOCTOU
|
|
50
|
+
- 逻辑缺陷且无明确 spec 可比对
|
|
51
|
+
- 标准验证走不出结论,或被升级
|
|
52
|
+
- 用户明确要求
|
|
53
|
+
|
|
54
|
+
**默认从标准开始。** 标准验证内置两个升级检查点:
|
|
55
|
+
|
|
56
|
+
1. Step 1 之后:若出现 3 个以上信任边界、回调/异步控制流,或含糊的校验链 → 升级
|
|
57
|
+
2. Step 5 之后:若任一问题产生无法解决的真实不确定性 → 升级
|
|
58
|
+
|
|
59
|
+
**升级时交出迄今全部证据**,深验证从停下的地方继续,**不重复已完成的工作**。
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## C.2 标准验证 6 步
|
|
64
|
+
|
|
65
|
+
### 第 1 步:数据流
|
|
66
|
+
|
|
67
|
+
1. 绘制跨越的信任边界(内部可信 vs 外部不可信)
|
|
68
|
+
2. 识别 source 与 sink 之间**所有**校验与净化
|
|
69
|
+
3. 查 API 契约——有些 API 自带边界保护
|
|
70
|
+
4. 查环境防护,并**区分**「彻底阻止」与「只抬高门槛」
|
|
71
|
+
5. 应用对应缺陷类别的专项检查(`bug-classes.md`)
|
|
72
|
+
|
|
73
|
+
> **陷阱:孤立分析代码。** 上游的条件逻辑可能让缺陷在数学上不可达。
|
|
74
|
+
> 必须追完整校验链,不能只看危险操作附近那几行。
|
|
75
|
+
|
|
76
|
+
### 第 2 步:可利用性
|
|
77
|
+
|
|
78
|
+
- **攻击者控制**:可信组件写入的内部存储**不是**攻击者可控的
|
|
79
|
+
- **边界证明**:写出显式代数证明,验证「IF 校验通过 THEN 边界保证成立」
|
|
80
|
+
- **竞争可行性**:单线程初始化、已同步的上下文**不可能**有竞争
|
|
81
|
+
|
|
82
|
+
### 第 3 步:影响
|
|
83
|
+
|
|
84
|
+
- 区分**真实安全影响**(RCE、提权、信息泄露)与**运维健壮性**(崩溃恢复、清理失败)
|
|
85
|
+
- 区分**主要安全控制**与**纵深防御**
|
|
86
|
+
|
|
87
|
+
### 第 4 步:演示草图
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
数据流: [Source] → [校验?] → [变换?] → [脆弱操作] → [影响]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
写清:攻击者控制什么、怎么控制、触发伪代码。
|
|
94
|
+
|
|
95
|
+
### 第 5 步:恶魔代言人抽查(7 问)
|
|
96
|
+
|
|
97
|
+
反对 5 问(防**假阳性**)+ 支持 2 问(防**假阴性**,标为 always ask)。
|
|
98
|
+
|
|
99
|
+
见 C.5。
|
|
100
|
+
|
|
101
|
+
### 第 6 步:门禁复核
|
|
102
|
+
|
|
103
|
+
走全部 6 门禁 + 全部 13 条误报清单。
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## C.3 六个门禁(全部通过才可报为漏洞)
|
|
108
|
+
|
|
109
|
+
| # | 门禁 | 判据 | 通过 | 失败 |
|
|
110
|
+
|---|---|---|---|---|
|
|
111
|
+
| 1 | **流程** | 所有阶段完成且有书面证据 | 每阶段都有证据 | 阶段缺具体证据 |
|
|
112
|
+
| 2 | **可达性** | 攻击者能到达并控制该处数据 | 有攻击者控制路径的明确证据 + PoC 确认 | 无法证明控制或可达 |
|
|
113
|
+
| 3 | **真实影响** | 利用导致 RCE、提权或信息泄露 | 有具体场景的直接影响 | 仅运维健壮性问题 |
|
|
114
|
+
| 4 | **PoC 验证** | PoC 演示了攻击路径 | 展示了控制、触发与影响 | PoC 未能展示路径或影响 |
|
|
115
|
+
| 5 | **数学边界** | 数学分析确认脆弱条件可能发生 | 代数证明条件可能 | 数学证明校验阻止了它 |
|
|
116
|
+
| 6 | **环境** | 没有环境防护能完全阻止利用 | 防护未消除漏洞 | 环境防护完全阻断 |
|
|
117
|
+
|
|
118
|
+
### 裁定规则(写死)
|
|
119
|
+
|
|
120
|
+
| 条件 | 裁定 |
|
|
121
|
+
|---|---|
|
|
122
|
+
| 6 门禁**全部** `pass` | `TRUE POSITIVE` |
|
|
123
|
+
| 任一门禁 `fail` | `FALSE POSITIVE` |
|
|
124
|
+
| 无 `fail`,但有 `not_evaluated` | **`INCONCLUSIVE`** |
|
|
125
|
+
|
|
126
|
+
**关键规则**:任一阶段验证失败,要**记录失败证据并继续执行剩余阶段**;
|
|
127
|
+
只有**全部阶段完成后**才下 `FALSE POSITIVE` 裁定。
|
|
128
|
+
|
|
129
|
+
> `INCONCLUSIVE` 是 euthyna 相对 Trail of Bits 原始定义**新增**的出口。
|
|
130
|
+
> 原因:原始实现靠 Stop hook 无限强制继续直到补完,而 DSH 的 Stop hook
|
|
131
|
+
> **必须自带限流**(否则死循环),做不到无限强制。详见 `docs/dsh-stop-gate-zh.md`。
|
|
132
|
+
|
|
133
|
+
### 裁定格式(必须带证据)
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
BUG #3 FALSE POSITIVE — packet_handler.c:142 的整数下溢
|
|
137
|
+
门禁 5(数学边界)FAIL:第 98 行校验保证 packet_size >= 16,
|
|
138
|
+
故 (packet_size - header_size) >= 8。下溢在数学上不可能。
|
|
139
|
+
|
|
140
|
+
BUG #4 TRUE POSITIVE — 命令注入
|
|
141
|
+
门禁全部通过。证据:src/archive.js:42 (abc1234)
|
|
142
|
+
复现:node tools/poc.js
|
|
143
|
+
可利用性:EASY
|
|
144
|
+
影响:以服务账号执行任意命令
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**格式由机器强制**:写完后用 `euthyna gate <报告文件>` 校验(见 SKILL.md「门禁的
|
|
148
|
+
程序化校验」一节)。TRUE POSITIVE 缺证据、缺复现、或带了 FAIL 门禁,会被校验器
|
|
149
|
+
**降级为「观察」**并以退出码 10 报出——纪律不依赖裁定者的自觉。
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## C.4 十三条误报清单(对**每个**疑似缺陷逐条应用)
|
|
154
|
+
|
|
155
|
+
| # | 条目 | 要问的问题 |
|
|
156
|
+
|---|---|---|
|
|
157
|
+
| 1 | **追踪完整校验链** | 危险操作之前,所有先行的校验是什么?不要分析孤立片段 |
|
|
158
|
+
| 1a | **映射完整条件逻辑流** | 看起来不安全的 `buffer[length-4]` 是否只在 `length > 12` 时可达? |
|
|
159
|
+
| 2 | **识别防御性编程** | `ASSERT(size == expected)` 是防御,不是漏洞 |
|
|
160
|
+
| 3 | **确认可利用的数据路径** | 只报有**已确认**可利用数据流的漏洞;不要假设网络数据会到达危险函数 |
|
|
161
|
+
| 4 | **理解数据源上下文** | API 返回值、编译期常量、网络数据的风险等级不同。判定真实来源 |
|
|
162
|
+
| 5 | **分析边界校验逻辑** | 若校验了 `size >= MIN` 且 `MIN >= sizeof(header)`,减法**不可能**下溢 |
|
|
163
|
+
| 6 | **核验 TOCTOU 主张** | 被检查的值能在检查与使用之间改变吗?同函数内检查后立即使用且无外部修改 = 无 TOCTOU |
|
|
164
|
+
| 7 | **理解 API 契约与信任边界** | 有些 API 自带边界保护,无论输入如何都不越界写 |
|
|
165
|
+
| 8 | **区分内部存储与外部输入** | 配置存储、注册表由可信组件控制,**不是**攻击者可控 |
|
|
166
|
+
| 9 | **不要把模式识别当成漏洞分析** | 「看着脆弱」的代码可能因上下文与 API 契约而安全 |
|
|
167
|
+
| 10 | **核验并发访问确实可能** | 单线程初始化上下文不可能有竞争;核验线程模型与同步机制 |
|
|
168
|
+
| 11 | **评估真实 vs 理论影响** | 非关键数据的存储失败是运维问题。问:会导致代码执行、提权或信息泄露吗? |
|
|
169
|
+
| 12 | **区分纵深防御与主要控制** | 主要防护存在时,纵深防御失效不一定是漏洞 |
|
|
170
|
+
| 13 | **严格而非表面地应用本清单** | 有清单不等于防住误报。**每个**疑似漏洞都要走完**全部**条目 |
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## C.5 恶魔代言人(双向对称怀疑)
|
|
175
|
+
|
|
176
|
+
这是全套设计里最精妙的一处:**它同时防假阳性和假阴性**。
|
|
177
|
+
|
|
178
|
+
### 反对缺陷(11 问,防假阳性)
|
|
179
|
+
|
|
180
|
+
1. 我是否在**幻觉**这个缺陷?(模型偏向于到处看到 bug 并把它们全评为 critical)
|
|
181
|
+
2. 我是否在做**模式匹配**而非分析?
|
|
182
|
+
3. 我是否**混淆了信任边界**?
|
|
183
|
+
4. 我的证明是否**严谨**?(有没有「大概率」「应该」)
|
|
184
|
+
5. 我是否把**纵深防御**当成了主要控制?
|
|
185
|
+
6. 攻击者真的**控制**这个输入吗?
|
|
186
|
+
7. 这个路径真的**可达**吗?
|
|
187
|
+
8. 我是否**忽略了上游的校验**?
|
|
188
|
+
9. 环境防护是否**完全阻止**了利用?
|
|
189
|
+
10. 影响是**真实的**还是运维层面的?
|
|
190
|
+
11. 我是否**高估了严重性**?
|
|
191
|
+
|
|
192
|
+
### 支持缺陷(2 问,**任何情况下都要问**,防假阴性)
|
|
193
|
+
|
|
194
|
+
12. **我是否因为利用方式复杂或不太可能,就否定了一个真实的缺陷?**
|
|
195
|
+
13. **我是否编造了未在源码中验证的缓解措施或校验逻辑?**
|
|
196
|
+
→ 得出结论后**重读代码**。
|
|
197
|
+
|
|
198
|
+
> 第 12、13 问是防假阴性的关键。模型的默认偏差是「报太多」,
|
|
199
|
+
> 所以大多数防误报机制都在压制它;但压制过头就会漏掉真实缺陷。
|
|
200
|
+
> 这两问是对称的配重,不许跳过。
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## C.6 深验证的任务依赖结构
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
Phase 1: 1.1 绘信任边界 + 追数据流
|
|
208
|
+
├─ 1.2 研究 API 契约与安全保证 ┐
|
|
209
|
+
├─ 1.3 环境防护分析 ├─ 均被 1.1 阻塞
|
|
210
|
+
└─ 1.4 交叉引用分析 ┘
|
|
211
|
+
Phase 2(被 P1 阻塞): 2.1 确认攻击者控制输入 ┐
|
|
212
|
+
2.2 数学边界验证 ├─ 并行
|
|
213
|
+
2.3 竞争条件可行性证明 ┘
|
|
214
|
+
└→ 2.4 对抗性分析(被 2.1/2.2/2.3 阻塞)
|
|
215
|
+
Phase 3(被 P2 阻塞): 3.1 证明真实安全影响 ┐ 并行
|
|
216
|
+
3.2 主要控制 vs 纵深防御 ┘
|
|
217
|
+
Phase 4(被 P3 阻塞): 4.1 伪代码 PoC + 数据流图(始终必做)
|
|
218
|
+
├─ 4.2 可执行 PoC(若可行) ┐
|
|
219
|
+
├─ 4.3 单元测试 PoC(若可行)├─ 并行
|
|
220
|
+
└─ 4.4 Negative PoC ┘
|
|
221
|
+
└→ 4.5 验证 PoC 确实演示漏洞
|
|
222
|
+
Phase 5(被 P4 阻塞): 5.1 恶魔代言人复核(13 问)
|
|
223
|
+
Gate Review(被 P5 阻塞): 6 门禁评估 → 裁定
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 执行规则
|
|
227
|
+
|
|
228
|
+
- 任务开始时标 in-progress,**只有具体证据才标 completed**
|
|
229
|
+
- 并行子阶段用子代理并发启动;进入下一依赖门禁前**收齐所有结果**
|
|
230
|
+
- **依赖未全部完成,绝不开始该阶段**
|
|
231
|
+
- **Phase 3 / Phase 5 / Gate Review 不得委派**——它们需要跨阶段综合
|
|
232
|
+
|
|
233
|
+
### 子代理权限刻意不对称
|
|
234
|
+
|
|
235
|
+
| 子代理 | 权限 |
|
|
236
|
+
|---|---|
|
|
237
|
+
| 数据流分析 | **只读** |
|
|
238
|
+
| 可利用性验证 | **只读** |
|
|
239
|
+
| PoC 构建 | 唯一有写权限 |
|
|
240
|
+
|
|
241
|
+
**制造证据的能力只集中在一个阶段**,前置阶段只能观察——降低污染证据的风险。
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## C.7 PoC 规则
|
|
246
|
+
|
|
247
|
+
### 可行性跳过条件(跳过必须带理由)
|
|
248
|
+
|
|
249
|
+
**可执行 PoC**:
|
|
250
|
+
|
|
251
|
+
- 需要本地不可用的硬件或网络
|
|
252
|
+
- 目标语言运行时未安装
|
|
253
|
+
- 利用需要**修改**生产代码(而非调用它)
|
|
254
|
+
- 缺陷在闭源组件
|
|
255
|
+
|
|
256
|
+
**单元测试 PoC**:
|
|
257
|
+
|
|
258
|
+
- 项目没有测试基础设施
|
|
259
|
+
- 脆弱代码无法孤立调用(深依赖链且无测试夹具)
|
|
260
|
+
- 构建系统损坏
|
|
261
|
+
|
|
262
|
+
### PoC 验证 5 问
|
|
263
|
+
|
|
264
|
+
1. 伪代码是否准确追踪了第 1 步的数据流?
|
|
265
|
+
2. 可执行 PoC 是否**真的运行**并展示影响?(要捕获**真实输出**,不是预期输出)
|
|
266
|
+
3. 单元测试是否通过并演示问题?
|
|
267
|
+
4. Negative PoC 是否正确识别了前置条件?
|
|
268
|
+
5. **是否存在人为绕过**(mock、stub、禁用检查)?——**有则 PoC 无效**
|
|
269
|
+
|
|
270
|
+
### Negative PoC 的作用(不许省)
|
|
271
|
+
|
|
272
|
+
展示同一路径在**良性输入**下正常工作 → 展示利用所需的**具体前置条件** →
|
|
273
|
+
解释为何正常使用下不成立但攻击者可强制成立。
|
|
274
|
+
|
|
275
|
+
**这不是证明缺陷是假的**,而是记录安全与不安全条件的差量,对修复有用。
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## C.8 批量分诊
|
|
280
|
+
|
|
281
|
+
多个疑似 bug 时:
|
|
282
|
+
|
|
283
|
+
1. 先对**全部**跑第零步(重述常直接瓦解明显的误报)
|
|
284
|
+
2. 逐个独立路由
|
|
285
|
+
3. **先处理全部标准路由的,再处理深路由的**
|
|
286
|
+
4. 全部验证完后,检查**利用链**——单独未过门禁的发现可能组合成可行攻击
|
|
287
|
+
|
|
288
|
+
## C.9 最终汇总格式
|
|
289
|
+
|
|
290
|
+
1. 计数:X 个 TRUE POSITIVE、Y 个 FALSE POSITIVE、Z 个 INCONCLUSIVE
|
|
291
|
+
2. TRUE POSITIVE 列表:每条附简要漏洞描述
|
|
292
|
+
3. FALSE POSITIVE 列表:每条附简要拒绝理由
|
|
293
|
+
4. INCONCLUSIVE 列表:**每条附缺什么、为什么缺**
|