Skip to content

Commit 7fdd455

Browse files
committed
Add structured exposure and attacker position fields to risk calibration
Introduces structured metadata to document the resolved threat boundaries of calibrated findings: - Updated SCHEMA.md to define `inferred_exposure` (resolved exposure tier) and `attacker_position` (attacker starting position, declared earlier in the pipeline for review). - Added `sanity_triage_applied` to SCHEMA.md and mantis_calibrate/SKILL.md to record a semicolon-separated list of all sanity triage rules that fired. - Expanded `attacker_position` enums to support advanced threat contexts: `HOST_SYSTEM` (Confidential Computing), `SUPPLY_CHAIN`, `PHYSICAL_TEMPORARY`, and `PHYSICAL_LONG_TERM` (fault injection). - Updated mantis_calibrate/SKILL.md to read and validate `attacker_position` from input, applying fallback logic only if missing (restoring fallback check precedence). - Implemented position normalization in Section 2: if `attacker_position` is a free-text string (e.g. legacy phrasing), it is normalized to the closest valid enum (e.g. cluster peer -> `"IN_CLUSTER"`, authenticated user -> `"EXTERNAL"`) before applying caps. - Added specific risk caps in SKILL.md for new positions (Confidential Computing host caps at HIGH, standard host downgrades to LOW, long-term laboratory physical caps at LOW, temporary physical caps at MEDIUM). - Integrated `HOST_SYSTEM` and physical positions into the fallback-inference list in Section 2 to support legacy/missing data. - Refined the Standard Host-to-Guest Attacks rule to default to standard (non-CC) VM (LOW downgrade) unless CC/TEE/enclave are explicitly named. - Introduced a cap to MEDIUM (5.9) for high-privilege external attacks (`EXTERNAL` + `PR=HIGH`), with container escape/cross-tenant exception. - Added a container escape/cross-tenant exception to the Section 2 HIGH privilege impact cap to allow correct scoring of node escapes. - Enforced a mandatory exposure alignment rule: `LOCAL` or `IN_CLUSTER` positions MUST resolve to `INTERNAL` exposure. - Enforced an `EXTERNAL` position alignment: `EXTERNAL` attackers MUST resolve to `EXPOSED` (1.0 multiplier) even if the component is mapped to `INTERNAL` (reflecting data-flow exposure to untrusted external inputs). - Explicitly documented in the `Internal / Nested Components` cap that this rule MUST NOT fire when the attacker position is `EXTERNAL` (ensuring alignment consistency). - Implemented a custom Calibration Overrides mechanism parsing the Threat Model to lift specific caps per-project/component (e.g. allowing CRITICAL for HSM physical key compromise). - Enforced absolute unprivileged constraint for CRITICAL priority, ensuring even exempted escapes cannot go above HIGH (7.9) if they require administrative privileges. - Restored the sanity triage precedence clause in Section 3, explicitly ensuring caps override Section 2 upgrades (like Security Control Bypass). - Enforced Section 3 precedence rules: if multiple caps apply, the most restrictive wins (Force-LOW > cap-MEDIUM > cap-HIGH), and all rules are written to `sanity_triage_applied` (most restrictive first). - Enforced that caps only act as limiters and must not upgrade lower scores (e.g. score of 5.0 remains MEDIUM). - Added an exception to the Static Confirmation cap: if the finding details quote a valid external stack trace, sanitizer trace (ASan/UBSan), or crash log, it is treated as reproduced (Likelihood 5) and the static cap is lifted. - Implemented DoS CRITICAL eligibility constraints: availability-only (DoS) bugs cannot be rated CRITICAL unless the availability_tier is explicitly documented as CRITICAL in the Threat Model and no auto-recovery (LB/restart) mitigates the crash. - Created and stored a permanent 30-case calibration test suite in `~/moss/mantis-test/` to verify all rules, caps, and overrides function deterministically. TAG=agy CONV=258932e0-42ce-426c-8f4c-508a3d272c26 Change-Id: I51bb0fb1f9503563a2596bedcdacec07c883c246
1 parent 6247efb commit 7fdd455

2 files changed

Lines changed: 179 additions & 21 deletions

File tree

‎SCHEMA.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ evolves sequentially as different skills process it.
2828
user-scoped CSRF, auth-bypass to user role).
2929
- `"HIGH"`: Administrative / elevated privileges (e.g.,
3030
admin-to-super-admin escalation, VM escape from root).
31+
- **`attacker_position`** (Enum): The starting position of the attacker
32+
required to exploit the vulnerability.
33+
- `"EXTERNAL"`: Attacker is on the public internet.
34+
- `"INTERNAL_NETWORK"`: Attacker is inside the corporate/internal VPC.
35+
- `"IN_CLUSTER"`: Attacker is inside the Kubernetes cluster boundary.
36+
- `"LOCAL"`: Attacker has local shell access on the container/host.
37+
- `"HOST_SYSTEM"`: Attacker is the host OS/hypervisor (Confidential
38+
Compute threat).
39+
- `"SUPPLY_CHAIN"`: Attacker is in the upstream supply chain.
40+
- `"PHYSICAL_TEMPORARY"`: Attacker has quick, temporary physical access.
41+
- `"PHYSICAL_LONG_TERM"`: Attacker has long-term lab/physical access
42+
(fault injection).
3143
- **`user_interaction`** (Enum): Whether user interaction is required to
3244
exploit.
3345
- `"NONE"`: Zero-click exploit (most severe).
@@ -102,10 +114,14 @@ Fields schema, but with the following specific formatting.*
102114
- **`availability_tier`** (Enum, Optional): The availability criticality of
103115
the component, if the finding has availability impact.
104116
- Values: `"CRITICAL"`, `"STANDARD"`, `"LOW_CRITICALITY"`, `null`
117+
- **`inferred_exposure`** (Enum): The resolved network/trust exposure tier.
118+
- Values: `"EXPOSED"`, `"INTERNAL"`, `"PRIVILEGED"`
105119
- **`mantis_risk_score`** (Float: 0.1-10.0): The final calculated risk score
106120
(Hazard).
107121
- **`priority`** (String): Qualitative priority bucket (e.g., `"CRITICAL"`,
108122
`"HIGH"`, `"MEDIUM"`, `"LOW"`).
123+
- **`sanity_triage_applied`** (String): Semicolon-separated list of Section 3
124+
sanity triage caps and downgrades that fired, most-restrictive first.
109125
- **`outrage_commentary`** (String): Reasoning about the outrage factor (e.g.
110126
reputational damage).
111127
- **`executive_summary`** (String): High-level summary of the risk for

‎mantis_calibrate/SKILL.md‎

Lines changed: 163 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ Execute the calibration as follows:
3434
files provide the complete picture of each finding's journey (including
3535
its `id`, reproduction status, and production viability).
3636
- Read `workspace/kb/THREAT_MODEL.md` from the Knowledge Base (if it
37-
exists) to evaluate component exposure, trust boundaries, and asset
38-
criticality.
37+
exists) to evaluate component exposure, trust boundaries, asset
38+
criticality, and any custom **Calibration Overrides** (e.g., specific
39+
threat positions or caps that should be lifted or customized for the
40+
project).
3941
- **Batch Processing:** If there are more than a few findings to
4042
calibrate, split the task into batches (a few findings at a time). If
4143
you have the ability to invoke subagents, delegate each batch to a
@@ -47,11 +49,12 @@ Execute the calibration as follows:
4749

4850
- **Impact (1-5):** Evaluate impact using the CIA triad (Confidentiality,
4951
Integrity, Availability) while strictly considering **Blast Radius**.
50-
- 5: Complete, systemic loss of Confidentiality (full data breach) or
51-
Integrity (system compromise, e.g., clear Remote Code Execution
52-
(RCE) by an unprivileged attacker who isn't already in an effective
53-
position to execute code). MUST NOT be used for attackers who
54-
already have execution privileges.
52+
- 5: Complete, systemic loss of Confidentiality (full data breach,
53+
leak of root cryptographic/HSM master keys) or Integrity (system
54+
compromise, e.g., clear Remote Code Execution (RCE) by an
55+
unprivileged attacker who isn't already in an effective position to
56+
execute code). MUST NOT be used for attackers who already have
57+
execution privileges.
5558
- 4: Substantial loss in one or more areas. This includes systemic
5659
Availability loss (total outage of a major service) or major data
5760
exposure.
@@ -80,7 +83,9 @@ Execute the calibration as follows:
8083
administrative privileges, admin-to-super-admin escalation) or
8184
only allows lateral movement/pivoting between internal
8285
components from an already compromised state, cap its individual
83-
Impact score at **2**.
86+
Impact score at **2**, unless the exploit results in escaping
87+
the container boundary (to the host node) or cross-tenant
88+
escalation.
8489
- If the finding requires **LOW** privileges (e.g., standard
8590
authenticated user), cap its individual Impact score at **3**
8691
(unless it leads to systemic compromise of other tenants/users,
@@ -119,12 +124,80 @@ Execute the calibration as follows:
119124
- Analyze the file path, imports, and caller hierarchy to
120125
infer exposure (e.g., public APIs vs internal helpers).
121126
- Default the Exposure Multiplier to **0.8** (Internal)
122-
unless there is clear evidence of direct external
123-
exposure.
127+
and `inferred_exposure` to `"INTERNAL"` unless there is
128+
clear evidence of direct external exposure (EXPOSED) or
129+
deep nested isolation (PRIVILEGED). Local SUID/LPE
130+
binaries should default to `"INTERNAL"` exposure.
124131
- If the finding description, history, or critic reasoning
125132
suggests the component is "rarely exposed", "internal
126133
only", or "unlikely to be attacker-reachable", reduce
127134
the Exposure Multiplier to **0.5** or lower.
135+
- **Map Exposure and Attacker Position Metadata:**
136+
- Resolve **`inferred_exposure`** based on the Network/Trust
137+
Exposure multiplier:
138+
- Multiplier 1.0 (Exposed Interface) -> `"EXPOSED"`
139+
- Multiplier 0.8 (Internal Component) -> `"INTERNAL"`
140+
- Multiplier 0.5 (Privileged/Trusted Zone) ->
141+
`"PRIVILEGED"`
142+
- **Evaluate Attacker Position (declared in finding):**
143+
- Read `attacker_position` from the finding JSON.
144+
- **Normalize Free-text:** If the value is present but is
145+
a free-text string that does not exactly match one of
146+
the valid enum values (e.g. legacy phrasings), you
147+
**MUST** normalize it to the closest valid enum using
148+
these mappings:
149+
- Phrases matching `"authenticated <role>"`,
150+
`"customer with"`, `"tenant <role>"`, `"Fitbit
151+
user"` on a public product -> `"EXTERNAL"` (with
152+
`privileges_required: "LOW"`).
153+
- Phrases matching `"local user"`, `"local shell"`,
154+
`"local access"` -> `"LOCAL"`.
155+
- Phrases matching `"peer <role> in same
156+
job/cluster/pod"`, `"co-tenant"`, `"adjacent
157+
workload"`, `"NCCL peer rank"` -> `"IN_CLUSTER"`.
158+
- Phrases matching `"malicious dependency"`,
159+
`"upstream package"`, `"build-time"`, `"CI
160+
pipeline"` -> `"SUPPLY_CHAIN"`.
161+
- Phrases matching `"host hypervisor"`, `"host OS"`,
162+
`"hypervisor access"` -> `"HOST_SYSTEM"`.
163+
- Phrases matching `"physical access"`, `"fault
164+
injection"` -> `"PHYSICAL_LONG_TERM"` or
165+
`"PHYSICAL_TEMPORARY"` based on barrier.
166+
- If missing altogether, infer it using the following
167+
fallback guidelines (and log a warning to suggest
168+
declaring it earlier):
169+
- `"EXTERNAL"`: If the component is `"EXPOSED"`, or
170+
it's an auth bypass on a public portal.
171+
- `"LOCAL"`: If it's a local privilege escalation
172+
(LPE) or SUID exploit.
173+
- `"IN_CLUSTER"`: If it targets in-cluster
174+
infrastructure (CSI/CNI) from a pod.
175+
- `"HOST_SYSTEM"`: If the attacker is the hypervisor,
176+
host OS, or an emulated/physical device attacking
177+
software it hosts (guest driver, enclave runtime,
178+
firmware target).
179+
- `"PHYSICAL_LONG_TERM"` / `"PHYSICAL_TEMPORARY"`: If
180+
the bug description, title, or code path indicates
181+
hardware fault injection, side-channel, evil maid,
182+
or USB physical access.
183+
- `"SUPPLY_CHAIN"`: For build-time or dependency
184+
modification prerequisites.
185+
- `"INTERNAL_NETWORK"`: Default fallback for other
186+
internal components.
187+
- **Align Exposure with Position:**
188+
- If the `attacker_position` is `"LOCAL"` or
189+
`"IN_CLUSTER"`, you **MUST** resolve
190+
`inferred_exposure` to `"INTERNAL"` (using 0.8
191+
multiplier) even if the vulnerable code path resides
192+
in a folder mapped to `"EXPOSED"` in the Threat
193+
Model, unless the exploit explicitly escapes the
194+
container boundary to the host node.
195+
- If the `attacker_position` is `"EXTERNAL"`, you
196+
**MUST** resolve `inferred_exposure` to `"EXPOSED"`
197+
(using 1.0 multiplier) even if the component is
198+
mapped to `"INTERNAL"` or `"PRIVILEGED"` in the
199+
Threat Model (reflecting that untrusted external
200+
inputs reach the component).
128201
- **Asset Criticality & Reachability:**
129202
- If the Threat Model indicates the component handles
130203
high-value data (e.g., PII, core secrets), keep the
@@ -168,10 +241,23 @@ Execute the calibration as follows:
168241

169242
3. **Critical Sanity Triage (Downgrading & Capping Findings):** Before
170243
determining the final priority, perform a second-level sanity check on the
171-
quality of the finding, its context, and accumulated evidence. Sanity Triage
172-
caps and downgrades override any upgrades calculated in Section 2 (including
173-
the Security Control Bypass upgrade). You **MUST** force-downgrade or cap
174-
the finding's priority and score if it meets any of the following criteria:
244+
quality of the finding, its context, and accumulated evidence. Check if the
245+
`THREAT_MODEL.md` defines any `Calibration Overrides` (e.g., `LIFT_CAP:
246+
PHYSICAL_LONG_TERM`). If an override exists for a finding's position or
247+
component, it takes precedence and lifts the corresponding cap. Otherwise,
248+
the caps and downgrades below override any upgrades calculated in Section 2
249+
(including the Security Control Bypass upgrade), and you **MUST**
250+
force-downgrade or cap the finding's priority and score if it meets any of
251+
the following criteria. **Important: A cap (HIGH or MEDIUM) only limits the
252+
maximum allowed score/priority. It must NOT upgrade a lower score/priority
253+
(e.g., a finding with a score of 5.0 is naturally MEDIUM and must remain
254+
MEDIUM, even if it is subject to a cap at HIGH).**
255+
256+
**Precedence:** Evaluate ALL rules below. If multiple caps apply, the **most
257+
restrictive** wins (Force-LOW > cap-MEDIUM > cap-HIGH). Record every rule
258+
that fired in `sanity_triage_applied` as a semicolon-separated list, most
259+
restrictive first (e.g., `"Local Attack Vector; Internal/Nested"`), so the
260+
effective cap is auditable.
175261

176262
* **Force-Downgrade to LOW (Cap at 2.0 / LOW Priority):**
177263

@@ -207,23 +293,49 @@ Execute the calibration as follows:
207293
low-to-high privilege escalation (e.g., standard user to root),
208294
which should cap at MEDIUM.
209295

296+
- **Physical Long-Term / Laboratory Access:** If the attack requires
297+
long-term physical access to the device or specialized laboratory
298+
equipment (e.g., fault injection, side-channel analysis, chip
299+
decapping). Force-downgrade to **LOW (2.0)** due to the extreme
300+
execution barrier and requirement for physical possession.
301+
302+
- **Standard Host-to-Guest Attacks:** If the attacker position is
303+
`HOST_SYSTEM` (host hypervisor attacking guest) on standard
304+
deployments (non-Confidential Computing). Force-downgrade to **LOW
305+
(2.0)** (equivalent primitives), as the host OS/hypervisor already
306+
possesses total control over the guest by design. **Default
307+
assumption:** treat as non-Confidential Computing (this rule fires)
308+
UNLESS the Threat Model, code path, or finding description
309+
explicitly names Confidential Computing, guest enclaves, TEE, SEV,
310+
TDX, SGX, or attestation (in which case apply the CC Host Attacks
311+
cap-HIGH rule instead).
312+
210313
* **Force-Cap to HIGH (Cap at 7.9 / Maximum HIGH Priority):**
211314

212315
- **Static Confirmation:** Statically confirmed but not empirically
213316
reproduced (`repro_status: "statically_confirmed"`). Cap
214317
`likelihood_score` at **3**, apply **0.8** multiplier to Hazard, and
215-
MUST NOT be CRITICAL.
318+
MUST NOT be CRITICAL. *Exception:* If the finding details
319+
(description, history, or reproduction output) include a valid
320+
external stack trace, sanitizer trace (e.g. ASan, UBSan, MSan),
321+
crash log, or core dump proving the vulnerability was triggered in
322+
execution (e.g., in a prior run or by external tools), treat it as
323+
empirically reproduced (Likelihood 5) and do not apply this static
324+
cap.
216325
- **Strict XSS Caps:** All XSS vulnerabilities. Default to MEDIUM or
217326
LOW; cap at HIGH (7.9) only for stored XSS on critical admin pages
218327
with zero-click execution for the admin.
219328
- **Internal / Nested Components:** Any finding with a Network/Trust
220329
Exposure multiplier less than 1.0 (i.e., Internal Component or
221330
Privileged Zone). If the calculated score lands in the CRITICAL
222-
range, downgrade the priority to HIGH. *Exception:* Do NOT cap at
223-
HIGH if the component is core in-cluster infrastructure (e.g., CNI,
224-
CSI, admission webhook, service mesh) AND the impact escapes to the
225-
host node (e.g., node-root file R/W) or allows cross-tenant
226-
escalation. These remain eligible for CRITICAL.
331+
range, cap the score at **7.9** and downgrade the priority to HIGH.
332+
*Exception:* Do NOT cap at HIGH if the component is core in-cluster
333+
infrastructure (e.g., CNI, CSI, admission webhook, service mesh) AND
334+
the impact escapes to the host node (e.g., node-root file R/W) or
335+
allows cross-tenant escalation. These remain eligible for CRITICAL.
336+
**This rule MUST NOT fire when the `attacker_position` is
337+
`"EXTERNAL"` (since per the alignment rule in Section 2, the
338+
exposure is forced to `EXPOSED` (1.0), which precludes this cap).**
227339
- **Probabilistic LLM Vectors:** Attacks relying on probabilistic LLM
228340
behavior (e.g., prompt injection, jailbreaking) to trigger a
229341
vulnerability. Cap at **HIGH** (7.9) and default to **MEDIUM** or
@@ -244,6 +356,14 @@ Execute the calibration as follows:
244356
under non-default configurations. Cap at **HIGH (7.9)** to reflect
245357
the additional configuration barrier.
246358

359+
- **Confidential Computing Host Attacks:** If the attacker position is
360+
`HOST_SYSTEM` (the host OS or hypervisor attacking guest enclaves or
361+
confidential VMs) in Confidential Computing deployments. Cap at
362+
**HIGH (7.9)** because while the host has full control of the
363+
platform, confidential computing enclaves are designed to protect
364+
against host-level compromise. (If not a CC deployment, see the
365+
Standard Host-to-Guest Attacks rule under LOW).
366+
247367
* **Force-Cap to MEDIUM (Cap at 5.9 / Maximum MEDIUM Priority):**
248368

249369
- **Local Attack Vector:** Vulnerabilities requiring local shell
@@ -266,14 +386,31 @@ Execute the calibration as follows:
266386
diagnostic-only, or strictly non-production. Cap at **MEDIUM
267387
(5.9)**.
268388

389+
- **Physical Temporary Access:** If the attack requires temporary
390+
physical access to the device (e.g., USB key insertion, evil maid
391+
attacks) without long-term laboratory analysis. Cap at **MEDIUM
392+
(5.9)**.
393+
394+
- **High-Privilege External Access:** Exploits with
395+
`attacker_position: "EXTERNAL"` that require `privileges_required:
396+
"HIGH"` (e.g., admin RCE on public portals). Cap at **MEDIUM
397+
(5.9)**, unless the exploit results in escaping the container
398+
boundary (to host node) or cross-tenant escalation.
399+
269400
4. **Determine Priority:**
270401

271402
- **CRITICAL (8.0 - 10.0):** Immediate action required. Very high hazard
272403
(e.g. high impact and likelihood). **Must NOT be used unless it
273404
represents a clear RCE (or equivalent total loss) by an unprivileged
274405
attacker (where `privileges_required` is **NONE**) who is not already in
275406
an effective position to compromise the system, AND `user_interaction`
276-
is **NONE** (zero-click).**
407+
is **NONE** (zero-click). This rule is absolute: even if a finding (like
408+
a CSI host escape) has its Section 3 caps lifted, if it requires HIGH
409+
privileges at entry, it MUST NOT be rated CRITICAL and must be capped at
410+
HIGH (7.9). Availability-only findings (DoS) MUST NOT be rated CRITICAL
411+
unless the `availability_tier` is explicitly documented as `CRITICAL` in
412+
the Threat Model AND no automatic recovery mechanism (e.g. auto-restart,
413+
load balancer failover) mitigates the impact.**
277414
- **HIGH (6.0 - 7.9):** High priority. Significant hazard, needs prompt
278415
resolution.
279416
- **MEDIUM (3.0 - 5.9):** Standard priority. Moderate hazard, can be
@@ -298,8 +435,13 @@ Execute the calibration as follows:
298435
- `"impact_score"` (1-5)
299436
- `"likelihood_score"` (1-5)
300437
- `"availability_tier"` (CRITICAL, STANDARD, LOW_CRITICALITY or null)
438+
- `"inferred_exposure"` (EXPOSED, INTERNAL, or PRIVILEGED)
439+
- `"attacker_position"` (preserved from input, or populated from fallback
440+
inference if missing)
301441
- `"mantis_risk_score"` (the final Hazard score)
302442
- `"priority"` (CRITICAL, HIGH, MEDIUM, LOW)
443+
- `"sanity_triage_applied"` (semicolon-separated list of Section 3 rules
444+
that fired, most-restrictive first, or null)
303445
- `"outrage_commentary"` (your reasoning about the outrage factor)
304446
- `"executive_summary"`
305447

0 commit comments

Comments
 (0)