Files
msd-core/docs/zh-CN/explanation/security-model.md
Jakub Zych a9a7a328e6 refactor: hard-fork GSD -> MSD (Make Software Done)
Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD
across contents and paths, upstream package/repo coordinates -> @golem15/msd-core
and golem15com/msd-core. Deep links into upstream history, sibling upstream
packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is.

Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line,
package/plugin identity, regenerated lockfile, install-tree fixtures, derived
registries and benchmark baseline; migration checksum baseline re-locked
(MSD keeps its own install state, so no install had applied the old sums);
sort-order and regex-escaped expectations in tests adjusted.
2026-10-06 01:47:40 +02:00

11 KiB
Raw Blame History

MSD Core 安全模型

说明 — 本文档描述 MSD Core 为何采用当前的安全立场,以及各防护层如何协同工作。本文不是每个钩子参数的参考手册。有关 /msd-secure-phase 命令及其选项,请参阅命令文档。有关实现层面的钩子架构,请参阅架构文档 § 钩子系统。有关组织级安全基线(扫描器控制、事件处理清单、所有权模型),请参阅 SECURITY.md。


为何 AI 驱动的开发需要专项安全立场

传统代码编辑器不会代表用户执行任意软件包。MSD Core 会。其研究 → 计划 → 执行的流水线将从"命名一个软件包"到"运行 npm install <package>"、从"编写规划产物"到"将该产物用作 LLM 系统提示"的完整路径全部自动化。每一个自动化步骤都将人从环路中移除——而每次移除都是潜在的攻击面。

MSD Core 的安全模型围绕一个核心原则构建:纵深防御。没有任何单一控制措施被认为是完美的。多个相互重叠的层各自降低一类特定风险,共同使攻击面大幅难以利用——尽管并未彻底消除。本文档末尾的诚实总结说明了该系统无法防御的内容。


第一层 — 供应链保护:软件包合法性门控

威胁

AI 模型会产生幻觉性软件包名称。这并非边缘故障模式:2025 年的研究表明,AI 生成的软件包引用中约有 20% 是幻觉名称,与合法软件包并不对应。这些幻觉名称中有一部分——同一研究中约 43%——在提示词中持续重复出现,这意味着攻击者可以观察 AI 工具常见生成的名称,然后在 npm、PyPI 或 crates.io 上预先注册这些名称,并附带恶意的安装后脚本。这种技术称为 slopsquatting。

Slopsquatting 的隐蔽之处在于,通过 npm view 验证的幻觉名称看起来是合法的。注册表条目仅证明有人注册了该名称——并不能证明该软件包实现了 AI 所描述的功能,也不能证明它有任何合法用户,更不能证明其安装脚本是安全的。若没有门控,幻觉名称将无声地流过 MSD 的研究员 → 规划员 → 执行员流水线,最终在您的机器上作为 npm install <attacker-package> 运行。

门控机制

门控机制跨三个流水线阶段运行:

研究阶段。 当 msd-phase-researcher 推荐外部软件包时,它会对每个软件包运行 msd-tools query package-legitimacy check --ecosystem <npm|pypi|crates> <pkgs>。结果会以 ## Package Legitimacy Audit 表格的形式写入 RESEARCH.md。标记为 [SLOP](高置信度幻觉或攻击者注册)的软件包在保存前会从 RESEARCH.md 中完全删除,永远不会到达规划员。

规划阶段。 msd-planner 读取审计表。对于任何标记为 [SUS](可疑:新注册、下载量低、无源代码仓库,或命名模式接近某热门软件包)或 [ASSUMED](来自 WebSearch 而非直接注册表验证)的软件包,规划员会在安装步骤之前插入一个 checkpoint:human-verify 任务。该检查点包含指向注册表页面的直接链接,以及需要重点核查的内容:维护者历史、问题跟踪器活动、是否存在可疑的安装脚本。

执行阶段。 若安装失败,msd-executor 会触发检查点并停止。它不会静默地尝试备用软件包名称——因为备用名称本身可能也是恶意的。这是执行员行为定义中的明确规则(执行员代理定义中的 RULE 3)。

为何 WebSearch 软件包始终标记为 [ASSUMED]

通过 WebSearch 发现的软件包名称无论 npm view 是否成功,均标记为 [ASSUMED]。在注册表中存在的软件包不等于可以安全安装的软件包。npm view 仅证明注册,而非合法性。[ASSUMED] 标签与 [SUS] 触发相同的人工验证检查点,确保任何未经验证的网络发现推荐在安装前均须经过人工审核。

生态系统覆盖范围

研究员使用各生态系统专属的验证命令,而非单一通用检查:

  • Node.js:npm view
  • Python:pip index versions
  • Rust:cargo search

这覆盖了跨生态系统幻觉——根据 2025 年 USENIX 研究,其发生率约为 9%——即 AI 推荐的软件包存在于某个生态系统,但并不存在于实际使用的生态系统中。

优雅降级

若 slopcheck 不可用(未安装,或研究阶段 pip 安装失败),MSD 应用最严格的兜底策略:每个推荐软件包均标记为 [ASSUMED],规划员对每次安装均设置 checkpoint:human-verify 任务。研究和规划照常进行——系统不会因缺少工具依赖而硬性失败。这有意比正常流程更严格:slopcheck 不可用意味着每次软件包安装都会有人工检查点。

slopcheck 工具采用 MIT 协议,可通过 pip 安装。若该工具被废弃,[ASSUMED] 门控兜底策略确保人工检查点覆盖无论如何均能维持。


第二层 — 提示注入防御

威胁

MSD Core 生成的 Markdown 文件会成为 LLM 系统提示。研究流水线读取外部网页内容;规划流水线接受用户提供的文本(--text-file、--prd);执行流水线写入规划产物,这些产物稍后会作为代理上下文被重新读取。任何流入这些产物的用户可控文本都是潜在的间接提示注入向量——攻击者控制的字符串一旦进入系统提示,就会尝试覆盖代理指令或窃取信息。

防御机制

MSD Core 在三个层面应对提示注入。

输入验证(security.cjs)。 msd-core/bin/lib/security.cjs 模块是核心安全工具。它提供:

  • 路径遍历防护:用户提供的文件路径(--text-file、--prd)经过验证,确保解析在项目目录内,并显式处理 macOS /var → /private/var 符号链接解析
  • 提示注入检测:已知注入模式(角色覆盖、指令绕过、系统标签注入)在用户提供的文本进入任何规划产物之前进行扫描
  • 安全 JSON 解析:防止通过精心构造的 JSON 负载发动原型污染攻击的包装器
  • Shell 参数验证:传递给子 Shell 命令的参数在使用前经过验证

运行时钩子:msd-prompt-guard.js。 该钩子在每次针对 .planning/ 文件的 Write 或 Edit 调用时触发。它扫描待写入内容中的注入模式,与 security.cjs 相同(部分模式直接内联到钩子中以实现独立性——钩子不 require() 该模块,因此即使模块路径改变也能运行)。检测结果仅供参考:钩子记录发现但不阻止写入。其原因在于,对合法规划写入的误报拦截比二级扫描层漏掉一次注入更具破坏性。

运行时钩子:msd-read-injection-scanner.js。 该钩子在每次 Read 工具调用的输出时触发。它扫描刚刚读取的内容中在不可信内容中注入的指令——捕获攻击者在 MSD 即将纳入代理上下文的文件中嵌入指令的情况。

CI 扫描器。 prompt-injection-scan.security.test.cjs 作为测试套件的一部分,扫描所有代理、工作流和命令文件中嵌入的注入向量。这能捕获 MSD 源代码本身的注入尝试——例如,修改工作流文件以添加角色覆盖指令的供应链攻击。

读取注入扫描器与提示守卫的对比

两个钩子覆盖互补的攻击面。msd-prompt-guard.js 监视对规划产物的写入——捕获注入的植入。msd-read-injection-scanner.js 监视任何文件的读取——捕获来自外部内容的注入摄取(依赖项的 README、第三方配置文件、用户提供的文档)。两者共同覆盖了摄取 → 存储 → 再读取的完整生命周期。


第三层 — 仓库与依赖完整性

在 MSD 运行时行为的上游,open-gsd 组织在仓库和软件包层面实施控制。这些控制在 docs/security/baseline.md 中有完整文档,此处为完整性摘要。

依赖完整性。 所有第三方依赖通过 package-lock.json 锁定,并在安装前与已发布的校验和进行验证。scripts/check-npm-integrity.cjs 门控在 CI 阶段检测版本无效、缺失软件包和多余软件包。这能缓解针对 MSD 自身依赖的依赖混淆和拼写抢注攻击。

密钥扫描。 每次提交和 PR 均扫描硬编码密钥。有意的测试夹具必须使用项目标准排除语法进行标注(标注格式见 SECURITY.md)。未标注的抑制项将导致 CI 失败。

区域设置安全文本扫描。 输出和面向用户的字符串会扫描 Unicode 同形字符、双向覆盖字符以及不可见 Unicode——即 CVE-2021-42574("特洛伊木马源代码")中记录的那类可在差异中隐藏恶意内容的攻击。


权衡与局限

本文描述的安全模型切实降低了 AI 驱动开发的攻击面,但并未消除供应链风险。

软件包合法性门控降低的风险: 幻觉或攻击者注册的软件包在没有人工检查点的情况下到达 npm install 的概率。[SLOP] 门控彻底删除高置信度的恶意软件包;[SUS] / [ASSUMED] 门控要求在执行前进行人工审核。这大幅提升了成功 slopsquatting 攻击的成本。

软件包合法性门控无法消除的风险: 之后遭到入侵的合法软件包(账户接管、其自身依赖树中的依赖混淆)不会被 slopcheck 捕获——slopcheck 在研究阶段检查注册信号。锁定文件和依赖完整性层的 npm audit 才是应对此类攻击的控制手段。

提示注入防御降低的风险: 规划产物中用户可控文本成功覆盖代理指令的概率。基于模式匹配的已知注入形式能捕获常见情况;新颖的越狱方法或低信号注入可能无法被检测到。仅供参考的立场意味着检测结果被记录但不会被阻止——这是一个经过深思熟虑的选择,以牺牲在检测时硬性停止为代价换取工作流的连续性。

提示注入防御无法消除的风险: 足够有创意的、与已知模式不匹配的注入,或通过钩子未覆盖渠道到来的注入(例如,注入到依赖项已发布 README 中、由子代理在浏览文档时读取的内容)。纵深防御意味着每一层使攻击更难——而非任何单一层使其不可能。

漏洞报告。 请通过 GitHub 私有安全公告提交,地址为 https://github.com/open-gsd/gsd-core/security/advisories/new。请勿开启公开 issue。响应时间表和披露政策请参阅 SECURITY.md。


相关文档