mcpField
M
mantis-threat-model

mantis-threat-model

github.com/google安全2.7k1.8k 次安装3 天前更新
代码仓库

关于 mantis-threat-model

此 findings-only 技能基于 Mantis 的架构和实体知识库文件生成并维护高层威胁模型。它描述信任边界、攻击者画像和高风险资产,记录快照来源,并在覆盖模型前归档旧版本。

主要功能

  1. 01读取知识库中的架构和实体文件
  2. 02识别信任边界与攻击路径
  3. 03记录高风险资产和可用性等级
  4. 04跟踪快照来源与新鲜度
  5. 05归档旧版威胁模型

适用场景

  1. 01根据现有架构知识库生成威胁模型
  2. 02知识库快照变更后重新推导模型
  3. 03按轮次保存旧模型以供审查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/google/mantis --skill mantis-threat-model

安装后在 Claude Code 中输入/mantis-threat-model确认已加载。

详细介绍

威胁建模器(/mantis-threat-model)

系统目标

安全架构师。仅基于知识库(KB)中定义的实体和架构,综合信任边界、攻击面和攻击者画像,生成 THREAT_MODEL.md。

命令定义

  • 命令: /mantis-threat-model
  • 描述: 评估架构边界、入口点和信任边界,以构建威胁模型。
  • 参数(均为可选;未提供 → 沿用今日行为):
    • --state_root <dir>:workspace/ 的父目录。若未提供,则使用相对于当前目录的 ./workspace/...。用于定位 .mantis_state.json、KB 和归档目录。
    • --snapshot_id <id>:本轮固定使用的 SNAPSHOT_ID。仅用作写入 THREAT_MODEL.md 的来源标记值(KB_SNAPSHOT: 行)。若未提供,则回退使用状态中的 active_snapshot.snapshot_id;若该值也不存在,或 snapshot_pinned 为 false,则标记为字面值 UNPINNED。
    • --snapshot_root <dir>:为保持接口统一而接受,但不会使用 —— 此阶段不会读取目标源代码(Block A 步骤 0,仅处理发现项)。

输入/输出约定

  • 读取:
    • workspace/.mantis_state.json —— pass_number(用于按轮次归档),以及仅用于来源追踪的 active_snapshot({root, snapshot_id, snapshot_pinned})。两者均可选;未提供 → 降级运行(参见向后兼容)。
    • workspace/kb/architecture.md。
    • workspace/kb/entities/*.md。
    • 上一轮留下的 workspace/kb/THREAT_MODEL.md(若存在)——仅读取其第一条 KB_SNAPSHOT: 行,用于步骤 0 的新鲜度检查。
  • 写入:
    • workspace/kb/THREAT_MODEL.md(第一行为 KB_SNAPSHOT: 来源标头)。
    • 覆盖前,将上一轮的 workspace/kb/THREAT_MODEL.md(若存在)归档至 workspace/archive/kb/THREAT_MODEL_pass_${N}.md。
  • 前置条件:
    • 知识库文件必须存在且已有内容。
  • 幂等性保证:
    • 将上一轮的 THREAT_MODEL.md(若存在)复制到本轮归档,然后以确定性方式原位覆盖 workspace/kb/THREAT_MODEL.md。在快照未变化的情况下重新运行本轮,会生成等效模型并附带 STALE 标记(参见步骤 0 和最终保存步骤)。

说明

LOCATOR RESOLUTION (before reading ANY target code or artifact):
0. ROLE: If this skill NEVER reads target source (report, calibrate, reflect),
   you are a FINDINGS-ONLY stage: skip steps 2-6; still read active_snapshot from
   state for provenance/annotation; NEVER stop merely because a code root is unset.
1. Determine CODE_ROOT, in this priority order:
   a. If --target_root is passed on THIS invocation, CODE_ROOT = --target_root.
      It is AUTHORITATIVE and OVERRIDES SNAPSHOT_ROOT and the state fallback
      (used when a caller hands you a prepared tree, e.g. a patched shadow).
   b. Else if --snapshot_root (or SNAPSHOT_ROOT) is passed, use it.
   c. Else read state_root/workspace/.mantis_state.json (state_root from
      --state_root if passed, else ./workspace/... relative to the current dir)
      -> active_snapshot.root / .snapshot_id / .snapshot_pinned.
   d. Else (no arg AND no readable active_snapshot): CODE_ROOT = current directory,
      treat snapshot_pinned = false (MODE-OFF). Do NOT stop.
2. SENTINEL CHECK (only if snapshot_pinned is true AND you did NOT take path 1a):
   verify CODE_ROOT/.mantis_snapshot_id exists and equals SNAPSHOT_ID. If missing
   or different -> STOP "snapshot sentinel mismatch". (A --target_root tree (1a) is
   deliberately mutated and is sentinel-EXEMPT.)
3. PATH FIELDS:
   - SNAPSHOT-RELATIVE (read under CODE_ROOT): code_paths entries; plan target_files
     that are file paths. Strip ONLY a trailing ":<digits>". A code_paths entry
     containing "://" is a URL/endpoint, NOT a file read. A code_paths entry that is
     NOT of the form <existing-path>:<integer> is a non-source LOCATOR
     (symbol/offset/endpoint): only check that the artifact/symbol exists; skip ALL
     line-range and line-existence logic.
   - STATE-RELATIVE (read/write under state_root/workspace, NEVER prefix CODE_ROOT):
     kb_references, repro_file_path, reattack_file_path, helper scripts, report
     files, and all state/findings JSON.
4. Never WRITE under CODE_ROOT when snapshot_pinned is true. Any command that
   compiles, generates, or writes artifacts MUST run in a PRIVATE SHADOW copy
   (mktemp -d from CODE_ROOT), never with cwd=CODE_ROOT. Read-only inspection may
   cd into CODE_ROOT.
5. VCS-METADATA CARVE-OUT: history-log extraction and any VCS diff/blame command
   run in the LIVE repository root (which still has .git/.hg/.repo), NOT CODE_ROOT
   (the snapshot copy strips VCS metadata). Do NOT stop merely because CODE_ROOT
   lacks .git/.hg/.repo.
6. Every shell command uses ABSOLUTE paths and sets its own working directory on
   that call. Do NOT assume the working directory persists between calls.

此阶段的角色(仅处理发现项 / 仅使用 KB)。 /mantis-threat-model 绝不读取目标源代码。它使用的每项输入 —— architecture.md、entities/*.md、上一轮的 THREAT_MODEL.md 和 .mantis_state.json —— 都是相对于状态目录的(在 state_root/workspace 下读取,绝不在 CODE_ROOT 下读取)。因此,此阶段采用 Block A 步骤 0 的“仅处理发现项”路径:跳过 Block A 步骤 2–6,但仍从状态中读取 active_snapshot 以追踪来源;绝不能仅仅因为代码根目录未设置或未固定就停止。

维护一份高层威胁模型,明确说明攻击者是谁以及他们可以在哪里与系统交互,并以 KB 中已预处理的实体为依据。

按以下步骤执行威胁建模:

  1. 解析快照来源、新鲜度,并归档上一轮模型:

    a. 计算 CUR(此威胁模型标记所依据的快照):

    • 若传入了 --snapshot_id → CUR = 该值。
    • 否则,若状态中的 active_snapshot.snapshot_pinned 为 true → CUR = active_snapshot.snapshot_id。
    • 否则 → CUR = 字面值 UNPINNED(降级运行 / 沿用今日行为)。

    b. **计算 PREV_TM(上一轮模型所依据的快照):**读取现有 workspace/kb/THREAT_MODEL.md 中符合 ^KB_SNAPSHOT: 的第一行;其值(去除首尾空白后)为 PREV_TM。若文件不存在、没有此类行,或值为空 → PREV_TM = 空字符串 ""。

    c. 同步差异判定(机械执行;严格字符串相等,不进行模糊比较):

    • CUR == "UNPINNED" → SYNC_OCCURRED = true(降级:始终重新推导)。
    • 否则,若 PREV_TM == "" → SYNC_OCCURRED = true(首次运行/旧版知识库)。
    • 否则,若 PREV_TM != CUR → SYNC_OCCURRED = true(同步或脏编辑推进了快照)。
    • 否则(PREV_TM == CUR)→ SYNC_OCCURRED = false(自上次建模以来快照未变)。

    d. 归档先前的模型(每次处理),以确保覆盖不会造成数据丢失:

    • 确定 N:从 workspace/.mantis_state.json 读取 "pass_number"。如果缺失或无效,则扫描 workspace/archive/,查找匹配 findings_pass_N 或 loopN_findings 的文件夹,并设 N = max_found + 1;如果不存在归档,则默认为 1。(与架构阶段使用相同规则。)
    • 如果 workspace/kb/THREAT_MODEL.md 存在:确保 workspace/archive/kb/ 存在(mkdir -p workspace/archive/kb/),并将文件复制(不要移动)到 workspace/archive/kb/THREAT_MODEL_pass_${N}.md。你将在步骤 3 中覆盖现有文件。如果文件不存在,则跳过复制。
    • 此步骤中的所有路径均相对于状态目录(位于 state_root/workspace 下);绝不要添加 CODE_ROOT 前缀。

    在步骤 1–3 和最终保存时,继续沿用 CUR、SYNC_OCCURRED 和 N。

  2. 读取综合知识库:

    • 读取 workspace/kb/architecture.md,了解系统的数据流和高层设计。
    • 读取 workspace/kb/entities/ 中的文件,了解各个组件,以及 /mantis-architecture 阶段映射到这些组件的历史约束或漏洞模式。
  3. 分析信任边界:

    • 评估各实体,确定信任边界所在的位置。不可信数据会在哪些地方进入可信上下文?哪些组件会接收外部输入?
  4. 综合威胁模型:

    • 编写一份全面、结构清晰的 Markdown 文件,并直接保存到 workspace/kb/THREAT_MODEL.md(覆盖旧文件)。
    • **Token 优化:**使用文件写入工具将文件直接写入磁盘;不要在聊天回复中输出威胁模型文本。

    请包含以下部分,确保下游规划 Agent 获得充足的上下文:

    • **系统概览摘要:**根据 architecture.md 编写简明摘要。

    • **部署意图:**准确写出 Intent: PRODUCTION 或 Intent: SAMPLE_OR_TEST_ONLY 中的一个。此判定的影响范围很大:/mantis-critic 一旦读取到 Intent: SAMPLE_OR_TEST_ONLY,就会将所有发现标记为 SAMPLE_OR_TEST(驳回本次处理的全部结果)。因此,SAMPLE_OR_TEST_ONLY 采用故障关闭机制,必须通过机械化检查清单:

      生产环境信号检查清单——只有在以下五项检查全部为 TRUE 时,才可以写入 Intent: SAMPLE_OR_TEST_ONLY。如果任何一项为 FALSE,知识库未提及任何一项,或你对任何一项不确定,则必须写入 Intent: PRODUCTION。

      1. workspace/kb/entities/*.md 中没有任何实体被分类为 CRITICAL 或 STANDARD 可用性(这两种分类都意味着有运行中的生产服务)。
      2. architecture.md 未提及任何可从外部访问的服务、守护进程、服务器、 API 或网络端点,也未提及任何部署/打包描述文件 (systemd、Dockerfile/docker、kubernetes/k8s/helm、负载均衡器、 云/VPC/IaC、CI/CD 发布或发行)。
      3. 知识库未描述任何可安装/发布的包或运行时入口点(例如 console_scripts/entry_points、main()/服务二进制文件、已发布的库或包清单)。
      4. 知识库中引用的每个组件/路径都仅位于测试/示例目录下——其路径包含 test、tests、example、examples、sample、samples、tutorial、demo、docs、 fixtures 中的一个——且没有任何组件/路径位于 src、 lib、pkg、internal、cmd、app、server 或 core 等生产源代码根目录下。
      5. 没有任何实体文档描述真实(非模拟、非测试)的不可信外部输入 越过信任边界进入特权/生产逻辑。

      同步后(步骤 0 中的 SYNC_OCCURRED == true),你必须根据当前知识库从头 重新运行此清单,且不得沿用先前的 Intent: 判定——同步可能会向此前仅含示例的树中添加生产代码, 否则可能会因此悄然忽略所有新发现。

    • 信任边界: 明确、严谨地定义不可信输入与内部可信状态相交的位置。引用具体实体 (例如 [Auth Module](entities/auth_module.md))。

    • 威胁行为者与攻击向量: 定义潜在攻击者的特征 (例如,未认证的网络攻击者、恶意本地用户)以及他们能够触及的具体边界。

    • 高风险资产: 攻击者试图破坏的数据、执行权限或可用性目标。对于可用性目标, 根据知识库将其归入以下某个可用性等级:

      • CRITICAL:中断会立即对 24/7 全天候运营造成影响。
      • STANDARD:重要运营;可容忍短暂停机。
      • LOW_CRITICALITY:非阻塞型实用工具;中断只会造成轻微不便。

为模型添加标记并保存:

  • workspace/kb/THREAT_MODEL.md 的第一行必须是来源标记 KB_SNAPSHOT: ,后接 CUR(来自步骤 0)——例如 KB_SNAPSHOT: <CUR>, 或在降级模式下使用 KB_SNAPSHOT: UNPINNED。下一轮会将其读回为 PREV_TM,而 mantis-critic 会将其用作知识库新鲜度检查。
  • 如果 SYNC_OCCURRED == false(自上次模型以来快照未变化):可以 复用先前模型的实质内容,但必须在 KB_SNAPSHOT: 行之后紧接着插入以下 STALE 横幅: > STALE: Threat model NOT re-evaluated this pass; carried unchanged from snapshot <CUR>. 如果 SYNC_OCCURRED == true:不要输出 STALE 横幅——本轮已重新推导 所有章节,包括部署意图清单。
  • 直接保存到 workspace/kb/THREAT_MODEL.md(相对于状态目录;先前文件已在步骤 0d 中复制到本轮存档)。使用文件写入工具;不要在聊天中输出模型。完成后通知用户。

评论

支持 Markdown