mcpField
S
security-audit

security-audit

github.com/donchitos安全29.1k463 次安装2 周前更新
代码仓库

关于 security-audit

security-audit 是一项游戏开发安全审查技能,可按指定范围协调审计并生成优先级整改报告。它检查存档、网络、输入验证、数据暴露等项目风险,并结合引擎和项目范围评估发现。

主要功能

  1. 01支持完整及定向审计范围
  2. 02检查存档与序列化风险
  3. 03审查网络和多人游戏安全
  4. 04检查输入验证与数据暴露
  5. 05生成优先级审计报告

适用场景

  1. 01在公开发布前审计游戏
  2. 02添加在线功能前审查安全性
  3. 03调查已报告的安全漏洞
  4. 04检查涉及磁盘或网络数据的改动

安装

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

$npx skills add https://github.com/donchitos/claude-code-game-studios --skill security-audit

安装后在 Claude Code 中输入/security-audit确认已加载。

详细介绍

!bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation,workflow

自动化模式:解析 modes.automation(project.local.yaml → project.yaml → 默认值 collaborative)。每次调用 AskUserQuestion 和 每次文件写入都遵循 .claude/docs/automation-modes.md (collaborative 每次都询问 · guided 仅重大事项询问 · autonomous 记录并继续; automation_always_ask 类别始终会提示)。

workflow(如上所解析)仅决定 Phase 7 如何告知你发布门槛的要求:standard 和 full 模式下需要此报告;minimal 模式下则不需要。无论处于哪个级别,审计本身的执行方式都相同。

安全审计

任何要发布的游戏都必须进行安全审计。即使是单人游戏,也存在存档篡改漏洞。多人游戏则面临作弊风险、数据泄露风险和拒绝服务攻击风险。此技能会系统性地审计代码库中最常见的游戏安全问题,并生成按优先级排序的修复计划。

运行此技能:

  • 公开发布前(workflow: standard 和 full 模式下,这是从 Polish 到 Release 的门槛要求)
  • 启用任何在线/多人游戏功能前
  • 实现任何从磁盘或网络读取数据的系统后
  • 收到安全相关的 Bug 报告时

输出: production/security/security-audit-[date]-[scope].md — 文件名中的范围可避免同一天运行的 quick 或 save 审计覆盖发布门槛所读取的 full 报告。


阶段 1:解析参数和范围

模式:

  • full — 所有类别(建议在发布前使用)
  • network — 仅网络/多人游戏
  • save — 仅存档文件和序列化
  • input — 仅输入验证和注入
  • quick — 仅高严重性检查(最快,适合迭代使用)
  • 无参数 — 运行 full

读取 project.yaml,确定以下内容;如果某个键缺失或为空,则在引擎/语言/平台方面回退使用 .claude/docs/technical-preferences.md:

  • engine.name 和 engine.language — 决定性信息:它们用于选择阶段 3 的模式集;如果某个类别没有适用于该引擎且有来源依据的模式集,该类别即为 NOT ASSESSED。 如果 engine.name 缺失或为空,请在报告中说明,并将每个 grep 类别都视为 NOT ASSESSED;不要回退使用 Godot 列表,因为这些列表是唯一完整写出的

  • platform.targets(会影响适用的攻击面)

  • platform.multiplayer 和 platform.online — 多人游戏/网络是否在范围内。technical-preferences.md 中没有对应字段,因此旧版回退机制无法提供这些值。

    缺失不代表 false。 这些键有读取方—— 此技能——但设置流程中没有写入方:/setup-engine 和 /start 都不会生成 platform: 块,只有有人运行 /settings 时才会设置这些键,所以大多数 CCGS 项目中这两个键都不存在。将它们默认为 false 会导致每个项目都跳过类别 2(网络和多人游戏安全)——连确实包含多人游戏的项目也不例外,让安全类别因一个无人设置的值而默认放行。

    如果任一键缺失或为空:不要假定是单人游戏,也不要跳过类别 2。 询问用户游戏是否包含多人游戏或在线功能。如果无法询问,仍然运行类别 2,并将其标记为 NOT ASSESSED — multiplayer scope unconfirmed (platform.multiplayer unset — set it with /settings);根据阶段 5 的规则,这会使 CLEAR TO SHIP 无法达成。 在范围尚未确认时,按多人游戏处理严重性——此时未解决的 HIGH 会导致 DO NOT SHIP——并在报告中说明评级假设游戏包含多人游戏,做法与 security-engineer 相同。 对单人游戏进行过度扫描只会多花几分钟;对多人游戏扫描不足,则会让该类别在未运行的情况下随游戏一同发布。

    使用 /settings platform.multiplayer=true 显式设置(这是项目级设置,因此会拒绝 --local)。修复方法是将其记录到 project.yaml;在有人这样做之前,本规则负责防范此问题。


阶段 2:启动 Security Engineer

通过 Agent 启动 security-engineer——审计是它的工作,因此不要在当前会话中自行运行这些类别。如果无法启动,请说明原因,在此处运行扫描,并在报告的审计者一行中如实说明。

发送以下固定简报模板。 仅填写 {…} 占位内容,依据 project.yaml(否则使用技术偏好)、按照 .claude/docs/code-root-resolution.md 解析出的代码根目录,以及照原文复制的阶段 3 文本。不要添加其他内容:不要对游戏类型发表看法,不要预判严重性,也不要对任何发现发表意见——任何自拟句子都可能导致预先评级。

Run a security audit of this project for /security-audit.

Scope: {full | network | save | input | quick}
Engine: {engine.name} {engine.version}, language {engine.language}
platform.multiplayer: {true | false | unset}    platform.online: {true | false | unset}    Phase 1 answer: {multiplayer | single-player | not asked}
Code root: {the resolved code root, or "unresolved"}
Also scan: {assets/data/ and the config files that exist, or "none"}
Categories to run, with their checks and grep patterns for this engine:
{each Phase 3 category this scope runs, copied as written, with the table's row for this engine}
NOT SOURCEABLE on this engine: {categories, or "none"} — report each NOT ASSESSED; never call it reviewed, verified safe or passed
Skipped, with reason: {e.g. "Category 2 — platform.multiplayer and platform.online are false", or "none"}
Report: production/security/security-audit-{date}-{scope}.md — return the report as text; /security-audit writes the file after asking

Severity (rate every finding yourself, against this table only):
- CRITICAL: Remote code execution, data breach, or trivially-exploitable cheat that breaks multiplayer integrity
- HIGH: Save tampering that bypasses progression, credential exposure, or server-side authority bypass
- MEDIUM: Client-side cheat enablement, information disclosure, or input validation gap with limited impact
- LOW: Defence-in-depth improvement — hardening that reduces attack surface but no direct exploit exists
Nothing in this brief sets or suggests a severity. The game's type never lowers a rating: a single-player game is rated on the same table. The one adjustment is upward — when the game is multiplayer, or its scope is unconfirmed (unset and not answered), a HIGH counts as CRITICAL; say so where it applies.
Report each finding as SEC-NNN with category, file:line, description, attack scenario, remediation and effort, grouped by severity.

模板已包含评级规则,因此无需重述:表格已将绕过进度系统的存档篡改评为 HIGH,Agent 会据此评估每项发现,阶段 5 则会在建议中应用多人游戏规则。

如果无法解析代码根目录,不要传入猜测的目录:每个扫描代码的类别都标记为 NOT ASSESSED — code root unresolved,并在报告中说明。如果代码根目录为空,则属于阶段 5 中实现不足的情况;每个扫描代码的类别都应标记为 NOT ASSESSED — no source under <root>,而不是零项发现。这两种情况都绝不能报告为干净。

security-engineer 会对 6 个类别进行审计(见阶段 3)。继续之前,先收集其完整发现。


第 3 阶段:审计类别

安全工程师将评估以下各项。跳过不适用于项目范围的类别,并在执行摘要中注明每个跳过的类别及原因(Category 2 — skipped: platform.multiplayer and platform.online are false)。

引擎模式集——请在查看以下任何类别之前阅读

**类别 1–3 中的所有模式列表均针对 Godot 编写。**在 Unity 或 Unreal 项目中,这些模式不会匹配任何内容;零命中扫描会让报告显示为干净, “这是安全审计中最危险的失败”。请根据第 1 阶段确定的 engine.name 使用下表。

类别GodotUnityUnreal
1 — 存档 / 序列化下方的 Godot 列表无法从资料中佐证无法从资料中佐证
2 — 网络 / 多人游戏下方的 Godot 列表ServerRpc、ClientRpc、NetworkVariable、NetworkObject、NetworkManager、NetworkBehaviour、IsServer、IsOwnerUFUNCTION、Server、Client、NetMulticast、Replicated、DOREPLIFETIME、GetLifetimeReplicatedProps、HasAuthority
3 — 输入下方的 Godot 列表InputSystem、PlayerInput、ReadValue、InputValueEnhancedInput、UInputAction、InputMappingContext、BindAction、FInputActionValue
4 — 数据暴露与引擎无关——下方列表适用于这三种引擎
5、6依靠判断和清单,而非 grep——无需引擎模式集

上述 Unity 和 Unreal 名称取自此仓库固定版本的参考资料(docs/engine-reference/unity/modules/{networking,input}.md、 docs/engine-reference/unreal/modules/{networking,input}.md),并非凭记忆写出。 使用前请对照固定版本验证,并补充参考资料中有记载但本表遗漏的内容——本表只是最低要求,并不完整。

**无法从资料中佐证 是一个判定,不是需要凭记忆填补的缺口。**这两棵 参考目录树都没有序列化 / 存档模块,因此无法在此确认 Unity 和 Unreal 的存档 API 名称。 **不要根据训练数据编写这些名称。**在此技能中,自信地列出错误模式比任何其他情况都更糟: 它会生成看似全面、却毫无发现的扫描结果,并让报告读起来像是通过了审计。对于表中标为 “无法从资料中佐证”的类别,该引擎对应的类别为 NOT ASSESSED ——请参阅第 5 阶段。若要妥善补齐,请将存档 / 序列化模块(按其他模块的方式提供来源) 添加到 docs/engine-reference/<engine>/modules/;添加后,从该模块中提取类别的模式名称, 在报告中引用该模块,并运行该类别。

类别 1:存档文件与序列化安全
  • 加载前是否会验证存档文件?(不盲目反序列化)
  • 存档文件路径是否由用户输入构造?(路径遍历风险)
  • 存档文件是否经过校验和或签名处理?(篡改检测)
  • 游戏是否会在未进行边界检查的情况下信任存档文件中的数值?
  • 存档加载附近是否有任何 eval() 或动态代码执行调用?

Grep 模式 — 信任此列表前,请先检查固定版本的引擎参考资料 (请参阅下方的 API 名称警告):FileAccess、File.open、open(、load、 deserialize、parse、parse_string、from_json、read_file、get_var、 bytes_to_var — 检查每处调用是否进行了验证。

API 名称因版本而异,此列表仅供参考,并不完整。 File.open 是 Godot 3.x 中的 API;Godot 4 将类名改为 FileAccess(docs/engine-reference/godot/breaking-changes.md)。依赖这些模式前,请先阅读 docs/engine-reference/<engine>/ 中与项目固定版本对应的资料,并补充其中记录的名称。对已不存在的类进行 grep 会返回零条匹配,而此类别中零条匹配会让报告显示为干净——这会造成安全审计中最危险的失误。如果只针对 Godot 4 项目搜索 File.open,就会一无所获,并在无人检查过的代码库上报告“可以发布”。如果无法确认固定版本对应的正确名称,请在报告中说明,而不要将零匹配扫描结果说成通过。

类别 2:网络与多人游戏安全(仅限单人游戏时跳过)
  • 游戏状态由服务端权威控制,还是由客户端决定结果?
  • 是否会验证传入网络数据包的大小、类型和值范围?
  • 是否会在服务端验证玩家位置和状态变化?
  • 网络调用是否有速率限制?
  • 身份验证令牌是否得到妥善处理(绝不以明文发送)?
  • 游戏是否会在发行版本中暴露任何调试端点?

Grep 搜索:recv、receive、PacketPeer、socket、MultiplayerPeer、 ENetMultiplayerPeer、NetworkedMultiplayerPeer、rpc、rpc_id、 @rpc — 检查每处调用是否进行了验证。

与类别 1 相同,需注意版本差异。NetworkedMultiplayerPeer 属于 Godot 3.x; Godot 4 使用 ENetMultiplayerPeer (docs/engine-reference/godot/modules/networking.md)。单独使用子字符串 MultiplayerPeer 搜索能匹配两者,是更稳妥的探查方式。

类别 3:输入验证
  • 玩家提供的字符串是否用于文件路径?(路径遍历)
  • 玩家提供的字符串是否未经清理就写入日志?(日志注入)
  • 数值输入(例如物品数量、角色属性)在使用前是否经过边界检查?
  • 成就或统计数据在写入任何后端前是否经过检查?

Grep 搜索:get_input、Input.get_、input_map、面向用户的文本字段 — 检查是否进行了验证。

类别 4:数据暴露
  • 代码根目录或 assets/ 中是否硬编码了任何 API 密钥、凭据或机密?
  • 发行版本中是否包含调试符号或详细错误消息?
  • 游戏是否会将玩家敏感数据记录到磁盘或控制台?
  • 是否会向玩家暴露任何内部文件路径或系统信息?

在面向发行版本的代码中不区分大小写地搜索:api[_-]?key、secret、 password、token、private[_-]?key、sk_live、BEGIN PRIVATE KEY、DEBUG, 以及引擎的打印调用(Godot 中的 print(、Unity 中的 Debug.Log、Unreal 中的 UE_LOG)。

类别 5:作弊与防篡改途径
  • 对游戏玩法至关重要的数值是否只存储在内存中,而不保存在容易编辑的文件中?
  • 任何关键的游戏进度标记(例如“已为 DLC 付费”)是否会在服务端验证?
  • 多人游戏是否有任何防范内存编辑工具(如 Cheat Engine)的保护措施?
  • 排行榜或分数提交是否经过验证后才会接受?

注意:客户端反作弊基本上无法强制执行。对于任何竞技性或变现相关内容,应重点关注服务端验证。

类别 6:依赖项与供应链
  • 是否使用了任何第三方插件或库?请列出。
  • 使用的版本中,是否有任何插件存在已知 CVE?
  • 是否已验证插件来源(官方市场、经过审核的代码库)?

搜索:addons/、plugins/、third_party/、vendor/ — 列出所有外部依赖项。


第 4 阶段:对发现进行分类

为每项发现指定:

严重程度:

级别定义
CRITICAL远程代码执行、数据泄露,或可轻易利用且破坏多人游戏完整性的作弊行为
HIGH篡改存档以绕过进度、凭据暴露,或绕过服务端权限控制
MEDIUM启用客户端作弊、信息泄露,或影响有限的输入验证漏洞
LOW纵深防御改进 — 加固措施可缩小攻击面,但不存在直接漏洞利用

状态: 未解决 / 已接受风险 / 超出范围


第 5 阶段:生成报告

# Security Audit Report

**Date**: [date]
**Scope**: [full | network | save | input | quick]
**Engine**: [engine + version]
**Audited by**: [security-engineer via /security-audit | this session — security-engineer not spawned: reason]
**Files scanned**: [N source files, N config files]

---

## Executive Summary

| Severity | Count | Must Fix Before Release |
|----------|-------|------------------------|
| CRITICAL | [N] | Yes — all |
| HIGH | [N] | Yes — all |
| MEDIUM | [N] | Recommended |
| LOW | [N] | Optional |

**Release recommendation**: [NOT ASSESSED — INSUFFICIENT IMPLEMENTATION / CLEAR TO SHIP / FIX BEFORE SHIPPING / DO NOT SHIP]

Choose it by the open findings, first match wins:
- **DO NOT SHIP** — any open CRITICAL finding (in a multiplayer game, any open HIGH
  counts as CRITICAL)
- **FIX BEFORE SHIPPING** — open HIGH findings and no CRITICAL; the Polish → Release
  gate needs zero open HIGH (at `standard` and `full`)
- **NOT ASSESSED** — per the rule below, when the scan could not cover the surface.
  It ranks below both failure values — a known finding is more actionable than an
  unscanned category, and still has to be fixed — and above CLEAR TO SHIP
- **CLEAR TO SHIP** — no open CRITICAL or HIGH (MEDIUM and LOW may remain)

> **`NOT ASSESSED` is required when there was not enough implemented surface to
> audit**, or when the API names for the pinned engine version could not be
> confirmed — **in place of CLEAR TO SHIP, never of a failure value.** An open
> CRITICAL or HIGH still decides the recommendation (first match above): a run
> with an unscanned category and an open HIGH is FIX BEFORE SHIPPING, and names
> the unscanned category beside it. A zero-finding scan over two files of source is not a clean bill of
> health, and `CLEAR TO SHIP` must never be reachable by having nothing to look
> at. Name what was missing and which skill produces it.
>
> **The engine axis is part of that rule, not a separate one.** If
> the Phase 3 table marks a category `NOT SOURCEABLE` for this project's
> `engine.name`, that category is `NOT ASSESSED` — state it by name in the
> Executive Summary, and **`CLEAR TO SHIP` is unreachable for the run**. The
> category reads `NOT ASSESSED — <category> has no sourced pattern set for
> <engine>`; the release recommendation is still the first match above, so it is
> NOT ASSESSED only where the run would otherwise have been CLEAR TO SHIP. Never
> report the category as reviewed by other means: files it covers may still be
> read for another category, and a finding that read turns up is reported, but
> the category stays NOT ASSESSED — never "reviewed", "verified safe" or passed.
> A scan that could not look is not a scan that found nothing, and only the
> report can tell the reader which of the two happened.

---

## CRITICAL Findings

### SEC-001: [Title]
**Category**: [Save / Network / Input / Data / Cheat / Dependency]
**File**: `[path]` line [N]
**Description**: [What the vulnerability is]
**Attack scenario**: [How a malicious user would exploit it]
**Remediation**: [Specific code change or pattern to apply]
**Effort**: [Low / Medium / High]

[repeat per finding]

---

## HIGH Findings

[same format]

---

## MEDIUM Findings

[same format]

---

## LOW Findings

[same format]

---

## Accepted Risk

[Any findings explicitly accepted by the team with rationale]

---

## Dependency Inventory

| Plugin / Library | Version | Source | Known CVEs |
|-----------------|---------|--------|------------|
| [name] | [version] | [source] | [none / CVE-XXXX-NNNN] |

---

## Remediation Priority Order

1. [SEC-NNN] — [1-line description] — Est. effort: [Low/Medium/High]
2. ...

---

## Re-Audit Trigger

Run `/security-audit` again after remediating any CRITICAL or HIGH findings.
At `workflow: standard` and `full`, the Polish → Release gate requires this report with no open CRITICAL or HIGH items.

第 6 阶段:撰写报告

在对话中展示报告摘要(执行摘要 + 仅包含 CRITICAL/HIGH 级别的发现)。

询问:“我可以将完整的安全审计报告写入 production/security/security-audit-[date]-[scope].md 吗?”

获得批准后再写入。


第 7 阶段:集成门禁

对于 workflow: standard 和 full,此报告是 Polish → Release 门禁的必需产物;minimal 门禁会省略此报告以及除冒烟测试和 S1 错误之外的所有内容。请根据上文解析出的 workflow,说明本项目适用哪种情况。

修复发现的问题后,重新运行:/security-audit quick,确认 CRITICAL/HIGH 项已解决,再运行 /gate-check release。

根据发布建议分支处理,而非仅根据发现数量:

如果建议为 DO NOT SHIP(存在未解决的 CRITICAL,或多人游戏中存在未解决的 HIGH):

“⛔ 必须先解决 CRITICAL 级别的安全发现,才能进行任何公开发布。在这些问题解决之前,请勿继续执行 /launch-checklist。”

如果建议为 FIX BEFORE SHIPPING(存在未解决的 HIGH、没有 CRITICAL,且是单人游戏):

在 workflow: standard/full 下:“⚠️ 仍有 [N] 项 HIGH 级别发现未解决。Polish → Release 门禁的安全审计项要求没有未解决项 — 请修复这些问题,并在运行 /gate-check release 前重新运行 /security-audit quick。”

在 minimal 下:“⚠️ 仍有 [N] 项 HIGH 级别发现未解决 — 请修复这些问题,并在发布前重新运行 /security-audit quick。minimal 发布门禁不会读取此报告;未解决的 HIGH 仍会导致建议为 FIX BEFORE SHIPPING。”

如果状态为 NOT ASSESSED:

“安全审计状态为 NOT ASSESSED — [列出每个未评估的类别及原因]。报告 已写入。[在 workflow: standard/full 下:] 在提供 [缺失的输入] 并 重新运行审计之前,/gate-check release 会将其安全审计项报告为 NOT ASSESSED。[在 minimal 下:] minimal 发布门禁不会读取此报告, 但在提供 [缺失的输入] 之前,这些类别仍未经过扫描。”

为每个类别指出缺失的输入:engine.name、代码根目录、多人游戏范围(/settings platform.multiplayer=…),或者 — 对于 Phase 3 表格中标记为此引擎不适用的类别(Unity 和 Unreal 上通常如此)— docs/engine-reference/<engine>/modules/ 中的存档/序列化模块(Phase 3),并指出该类别。

如果建议为 CLEAR TO SHIP:

“✅ 没有阻止发布的安全发现。报告已写入 production/security/。运行 /gate-check release 时请包含此路径。”


协作协议

  • 绝不假设某种模式是安全的 — 标记出来,让用户决定
  • 接受风险也是有效结果 — 对于单人团队而言,某些 LOW 级发现是可以接受的权衡;请记录此决定
  • 多人游戏的要求更高 — 在多人游戏场景中,任何 HIGH 级发现都应视为 CRITICAL
  • 这不是渗透测试 — 本次审计涵盖常见模式;在推出任何竞技型或商业化多人游戏之前,建议由专业安全人员进行真正的渗透测试

评论

支持 Markdown