☰
security-audit-skill:协议、RPC 与消息系统攻击面猎杀指南(Protocols, RPC Messaging Hunting)
2026/9/30 3:22:28 网站建设 项目流程
  • AI 技能
  • 应用安全

【免费下载链接】security-audit-skill

A coding-agent skill for multi-phase security audits with independently verified, machine-readable findings

项目地址:https://gitcode.com/GitHub_Trending/se/security-audit-skill
点击查看免费下载

本指南基于security-audit-skill仓库中的领域猎杀文档 PROTOCOLS-RPC-AND-MESSAGING.md,系统讲解如何对 gRPC、GraphQL、Thrift、Protobuf、自定义二进制协议、流式 RPC、Webhook、Broker、队列、Pub/Sub 与事件总线类目标展开安全审计。你将掌握四类攻击面(消息分帧与解释分歧、RPC 身份与授权、Broker 隔离、重放/排序/事务)的猎杀方法、跨组件对比思路,以及将候选证据收敛为confirmed或needs_validation的验证纪律。该技能以六阶段审计工作流为载体,本文件作为被选定注入猎手提示词的领域 Companion,与 SKILL.md、ATTACK-CLASSES.md、HUNTING.md 共同驱动一次可独立验证、机器可读的安全审计。

何时启用本文件:识别协议类目标与领域分工

PROTOCOLS-RPC-AND-MESSAGING.md的When to use this file段定义了明确的启用条件:当目标使用 gRPC、GraphQL 传输层、Cap'n Proto、Thrift、Protobuf、自定义二进制协议、流式 RPC、Webhook、Broker、队列、Pub/Sub 或事件总线时,就应当选择本 Companion。它聚焦四类核心审查对象:对等方身份(peer identity)、消息的逻辑解释(logical message interpretation)、路由、重放、排序与投递语义。

该文件同时明确了与其它领域 Companion 的边界,避免审计任务重叠或漏检:

  • 解析器的内存安全问题交给 MEMORY-SAFETY-AND-BINARY.md;
  • HTTP 层的分帧与身份协议问题交给 WEB-PROTOCOL-AND-AUTH.md;
  • 消息消费导致的可用性影响(如队列容量耗尽、Broker 投递逻辑引发的死锁)交给 RESOURCE-EXHAUSTION-AND-AVAILABILITY.md。

选择 Companion 不是依据语言或依赖名是否出现,而是依据侦察阶段(Phase 1)发现的信任敏感边界。这一原则在 RECONNAISSANCE.md 中有明确要求:"Do not select a companion file merely because the language or dependency name appears. Select it because reconnaissance found the trust-sensitive boundary described by itsWhen to use this filesection",即只有侦察确认存在由该文档所描述边界的信任敏感点,才应选中该文件,同时"每个可见边界都不能仅仅因为另一个 agent 会审查相关类别就排除"。

系统拆分建议:对于大型系统,按以下维度划分审计单元——生产者/消费者配对(producer/consumer pair)、外部与内部对等角色(external/internal peer role)、同步 RPC、流式(streaming)、异步消息路径。这种拆分与 Phase 1 生成确定性覆盖台账(coverage-ledger)的单元粒度对齐,每个"入口面 × 信任边界 × 子系统 × 攻击类"组合成为独立审计单元。

核心纪律:必须注入每个该领域猎手提示词的强制文本

无论选择哪几条具体攻击类,Core discipline段要求将其中的五条纪律逐字复制进每个该领域猎手的提示词(在 HUNTING.md 的 Required hunter prompt 中,选中的 Companion 的Core discipline、各攻击类小节、Universal moves与Validation rules均需完整注入,且"不得只发送块名或 Companion 名")。原文如下:

- "Internal" is not authentication. Name the peer identity at every hop and show how it becomes the application principal used for authorization. - Schema validation proves message shape, not provenance, resource authority, ordering, or safe values. Follow decoded fields to policy and side effects. - Broker guarantees and application guarantees differ. Write down retry, ordering, acknowledgement, deduplication, and transaction behavior before evaluating state changes. - Parser disagreement requires two concrete consumers, schema versions, or wire representations and one security-relevant divergent value. - Use `confirmed` for source-complete paths plus bounded local producer/consumer tests. Use `needs_validation` for broker ACL, service-mesh identity, topic attachment, or compatibility behavior outside the repository.

这五条纪律对应五类最常见的误判,逐一展开:

  1. "内部"不等于"已认证"。"internal" 只是网络拓扑或代码路径的描述,必须逐跳(hop)指明对等方身份,并说明它如何转化为授权使用的应用程序主体(application principal)。例如 gRPC 中一个请求经过 LB→网关→服务三个跳,每一跳的 mTLS 身份与最终授权主体的绑定关系都必须可追踪。
  2. Schema 校验只证明消息形状。Protobuf/Thrift 等 schema 校验通过只能说明字段类型合法,不能证明消息来源可信、资源权限合理、顺序正确或取值安全。审计必须沿着解码后的字段追踪到策略判断与副作用(side effect)。
  3. Broker 保证 ≠ 应用保证。Kafka 的 at-least-once、RabbitMQ 的 ack 语义、SQS 的 exactly-once 近似保证,与业务代码自己实现的幂等、事务边界是两个层面。在评估任何状态变更前,必须先写清楚重试、排序、确认(ack)、去重、事务行为,再下结论。
  4. 解析器分歧必须有双方证据。断言两个解析器对同一消息解释不一致,需要给出两个具体的消费者、schema 版本或线上表示(wire representation),外加一个"安全相关"的分歧值(例如 tenant 字段、权限字段)。任何一方的安全拒绝(safe rejection)都会使该断言无法被确认。
  5. 证据等级的硬性分界:源码路径完整 + 有界的本地生产者/消费者测试 → 可标记confirmed;涉及仓库外的 Broker ACL、服务网格身份、主题挂载或兼容性行为 → 必须标记needs_validation,并写明缺失的确切事实。

攻击类一:消息分帧、Schema 与解释分歧(Framing, schema, and interpretation)

本节由general子代理执行(subagent_type: general),包含三条攻击类:

消息边界与规范化分歧(Message boundary and canonicalization disagreement)

不同组件对消息的长度、压缩、重复字段、未知字段、编码、数值宽度、规范化、信封/正文优先级(envelope/body precedence)的理解不一致。典型场景包括:官方生成解析器与自研解析器对同一二进制流切分出不同的字段边界;网关对消息做了一次规范化而消费者又做了一次;版本转换器(version converter)在两代 schema 之间转换时丢字段或改默认值。

审计动作:对比生成解析器与自定义解析器、网关、各语言绑定(language bindings)与版本转换器;解码后确认受影响的"主体、资源或操作"是否不同。如果没有一个可指认的 principal/resource/operation 在解码后发生分歧,就不构成候选。这与 HUNTING.md 中 "TEST SAD PATHS AND DISAGREEMENTS" 的要求一致:只在接口接受的前提下测试缺失、空、零、负、最大、超限、重复、混合编码、陈旧、已撤销、乱序、并发、部分迁移、失败依赖与回滚状态,并在每次解析器/策略交接点比较规范化与单位(canonicalization and units)。

联合、枚举与默认值混淆(Union, enum, and default confusion)

未知变体、缺失判别符(discriminator)、零值、默认权限或兼容性映射,最终流入假定"已被校验为合法"的代码。例如:一个 union 字段在旧消费者看来是null而新消费者看来是admin;一个 enum 出现 schema 中未定义的序号时,某语言绑定抛出异常、另一绑定回落为默认值;新增字段被旧消费者忽略但恰好携带安全敏感语义。

审计动作:审查穷尽分发(exhaustive dispatch)、默认分支(default branch),以及旧消费者如何解释新添加的字段——这正是跨版本兼容攻击的温床。

信封与载荷身份不匹配(Envelope and payload identity mismatch)

授权逻辑信任"看起来可信的"路由或信封元数据(如 gRPC metadata 中的 tenant header、JWT 的某 claim),而处理器实际依据正文(body)中冲突的 tenant、账户、主题、对象或发送者执行动作。此时必须判断哪个来源是权威的(authoritative),并确认客户端能否覆盖它(override)。payload 里的租户文本不是隔离机制——这句在 Broker 章节会再次出现,是贯穿始终的原则。

攻击类二:RPC 身份与授权攻击类(RPC identity and authorization)

包含四条攻击类,全部聚焦"认证了什么"与"授权了什么"之间的错位:

拦截器与方法路径不一致(Interceptor and method-path inconsistency)

认证/授权拦截器(interceptor)覆盖了 unary 方法,却遗漏了:流式方法(streaming)、反射服务(reflection)、健康检查(health)、网关转码路径(gateway-transcoded paths)、兼容性服务、或单条流内逐条消息(individual stream messages)。审计动作:把每一处注册(registration)与路由(route)与同一个操作逐一比对,找出"看起来被保护、实际未被保护"的方法族。

对等身份与应用程序主体混淆(Peer identity to application-principal confusion)

mTLS、工作负载身份(workload identity)、Bearer 元数据、转发身份(forwarded identity)或 Broker 凭证只能认证通道(channel),但如果随后有一个调用者可控的字段(caller-controlled field)来选择用户或租户,就会发生混淆。通道身份与声明的 principal 必须由确定性策略绑定(deterministic policy)——例如 gRPC 中:authority元数据由客户端填充,若服务端拿它决定租户而 mTLS 身份来自不同主体,就是典型缺口。

逐项与流式授权缺口(Per-item and streaming authorization gaps)

一个流(stream)、订阅(subscription)、批量(batch)或群发(bulk)消息只被授权一次,但后续的每条消息可能指向不同的资源;或者订阅在角色、成员资格、令牌撤销之后继续存活。审计动作:在作用域(scope)可能变化的每个点重新做授权检查,并把订阅绑定到其原始主体(bind subscriptions to their original principal)。这也呼应 SKILL.md 的"Require a boundary and result"原则:每个候选都要指明低信任主体、被接受的动作、被跨越的控制、受影响的主体/资源与可观察结果。

回调与应答关联混淆(Callback and reply-correlation confusion)

可预测、可复用或跨租户的关联 ID(correlation ID),会让一个响应、Webhook、取消或确认(acknowledgement)满足另一个调用方的待处理操作。例如回复队列(reply queue)没有与请求绑定,任一消费者都能抢先取走应答。审计动作:把每个未决请求(outstanding request)绑定到已认证的对等方、租户、操作与生命周期。

攻击类三:Broker 与队列隔离攻击类(Broker and queue isolation)

包含三条攻击类,聚焦消息中间件的隔离边界:

主题、路由键与订阅范围缺口(Topic, routing-key, and subscription scope gaps)

发布者或订阅者可以选定另一租户的主题、通配符(wildcard)、消费组(consumer group)、分区、回复队列或死信路由。审计动作:在可见处检查 Broker 强制的 ACL,同时检查应用侧命名空间构造(namespace construction)。"Payload 内的租户文本不是隔离机制"——只有真正受控的命名空间与 ACL 才是。此处的难点在于 Broker ACL 通常不在仓库内,因此这类缺口往往以needs_validation上报,并写明需要验证的 Broker 名称与规则。

死信、重试与诊断泄露(Dead-letter, retry, and diagnostic disclosure)

被路由到死信队列(DLQ)、错误主题、追踪(tracing)或运维视图(operator views)的消息,可能包含机密或跨租户载荷,而消费这些失败路径的往往是一个低信任消费者。审计动作:审查失败路径上的策略与脱敏(redaction),而不仅审查正常投递路径。

不可信生产者被当作控制面(Untrusted producer treated as control plane)

一条消息正文可以自称是管理事件(admin event)、提供方回调(provider callback)、复制记录(replication record)或迁移指令(migration instruction),却没有独立认证的生产者与事件类型。审计动作:在执行特权处理前,验证签名以及 source/account/audience 绑定。这类攻击与 ATTACK-CLASSES.md 中的"Implicit trust assumptions"一致:不要把"数据来自某个组件"当作"已验证"。

攻击类四:重放、排序与事务攻击类(Replay, ordering, and transaction)

包含四条攻击类,聚焦消息系统的时序与一致性语义:

重复投递与幂等缺口(Duplicate delivery and idempotency gaps)

重试或重投递(redelivery)重复执行副作用,因为:去重缺失、去重发生在变更之后(deduplication after mutation)、或去重键(dedup key)跨租户/跨操作冲突。审计动作:确认 Broker 的投递模型(at-most-once / at-least-once / exactly-once),并确认哪个副作用天然不是幂等的(如扣款、写文件、发通知)。

乱序与陈旧消息接受(Out-of-order and stale message acceptance)

较旧的状态、已撤销的成员资格、已取消的工作或升级前(pre-step-up)的授权,在较新状态之后到达并覆盖它。审计动作:审查序号/版本检查(sequence/version checks)、墓碑(tombstones)、分区变更(partition changes)以及恢复/重放工作流(restore/replay workflows)。

确认/提交顺序缺陷(Acknowledgment/commit ordering defects)

确认(ack)发生在持久化提交之前,导致安全相关工作丢失;或提交发生在不可靠的确认之前,导致变更重复。审计动作:评估**事务性发件箱/收件箱(transactional outbox/inbox)**行为与故障恢复。

部分多消费者转换(Partial multi-consumer transitions)

多个消费者共同实现一个授权或业务转换,但重试与部分失败导致只有子集被提交(only a subset committed)。审计动作:识别哪些不变量必须原子地持久化(durable atomically),或用当前授权进行补偿(compensate with current authorization)。这与 ATTACK-CLASSES.md 中 Business logic 的"State machine violations / partial failure"攻击类呼应:步骤 2/3 失败时步骤 1 是否回滚。

通用动作:消息族链路图与最小夹具(Universal moves)

无论命中上述哪一类攻击,三条通用动作都必须执行,它们把零散攻击类收敛为可验证的审计路径:

  1. 逐消息族绘制链路图:对每个消息族(message family)画出producer → broker/transport → gateway → consumer → storage,在每一跳记录:已认证的对等方(authenticated peer)、权威的租户/资源字段(authoritative tenant/resource fields)、校验内容与副作用(side effect)。这条动作与 VALIDATION-AND-REPORTING.md 要求的"多步 trace 以entrypoint开头、以sink结尾、中间用propagation"的记录结构一一对应。
  2. 同一最小夹具喂给所有 schema 版本/语言绑定:把同一个小的测试夹具(small fixture)输入仓库内每一个schema 版本或语言绑定,测试重复(duplicate)、缺失(missing)、未知(unknown)、边界(boundary)、重放(replayed)与乱序(reordered)消息——且不产生负载(without producing load),这是 HUNTING.md "bounded local evidence"原则的落地方式:优先使用现有单元测试、最小函数 harness、dummy 租户服务调用、小畸形夹具。
  3. 横向对比全部路由形态:比较正常(normal)、重试(retry)、死信(dead-letter)、重放(replay)、迁移(migration)、反射(reflection)、流式(stream)与网关转码(gateway-transcoded)路由——安全策略必须能在传输方式变化后依然成立(Security policy must survive transport changes)。这直接对应攻击类二"拦截器与方法路径不一致"。

上报前的验证规则:从候选到 confirmed / needs_validation

在任何发现被上报之前,必须执行本文件Validation rules段的五条规则。这是该领域特有的"候选门槛"(candidate gate),与 HUNTING.md 的通用门槛以及 report-schema.json 的三分支记录契约相互咬合:

  1. 命名完整参与者链:指明现实的生产者或对等方(realistic producer or peer)、被接受的消息、已认证的通道身份、受影响的主体/资源,以及未授权的变更或泄露(unauthorized mutation or disclosure)。缺少任何一环,不构成候选。
  2. 分歧声明需要双方案据:对解析器分歧类声明,必须引用两个解析器/消费者与分歧的解码值(divergent decoded value)。任何一方安全拒绝(safe rejection)即可阻止确认——即如果任一端会安全地拒绝该消息,就没有可利用性。
  3. 重放/排序声明需要投递保证与本地复现:先确立实际的投递保证(actual delivery guarantees),再用有界的内存/本地传输(bounded local/in-memory transport)复现不变量失败,而不是在生产 Broker 上验证。
  4. 授权与隔离声明需核对所有可见层:核验源码中可见的全部拦截器、Broker ACL、网关与消费者层。外部挂件(external attachments)使候选降级为needs_validation——这正是 SKILL.md "Respect source visibility"原则的体现:部署控制、代理行为、Broker ACL 等真实控制若不在仓库内,既不能假定存在也不能假定缺失。
  5. 两种终态的判定标准:仅在拥有完整消息生命周期 + 可观察的真实结果时返回confirmed;若需要确切指明的 Broker、服务身份、路由或投递事实,则返回needs_validation,并给出所需的验证计划。

这三分支契约在 report-schema.json 中被形式化:confirmed记录必须携带root_cause、intended_behavior、trace、evidence、conditions、execution、remediation、severity、confidence且不得携带blockers或validation_plan;needs_validation记录必须携带claimed_root_cause、blockers与至少一个非空的validation_plan.local或validation_plan.deployment,且不得有严重度——needs_validation表示"被源码边界的假设被阻断",而非"低置信度的 confirmed 漏洞"。审计结束后由 validate-findings.cjs 校验这些约束。

在六阶段审计工作流中的定位

本文件不是独立运行的清单,而是被 SKILL.md 六阶段流程按需加载的领域 Companion,其生效路径如下:

  1. Phase 1 侦察(RECONNAISSANCE.md):research代理识别 RPC/消息/协议入口面(Agent 1c 明确把 "RPC/message/protocol" 列为入口面清单之一),父代理据此在覆盖台账的每个单元记录selected_companion_blocks(含FILE.md#Core discipline、各攻击类小节、Universal moves、Validation rules),并记录被排除的块及排除理由。
  2. Phase 2 猎杀(HUNTING.md):general猎手接收按顺序编排的提示词——角色序言、architecture.md原文、分配的覆盖 ID、逐字复制的选中块、排除块与理由、核心猎杀方法、核心验证规则、结构化结果契约。本文件的各攻击类小节即在此阶段注入。
  3. Phase 3 独立验证(VALIDATION-AND-REPORTING.md):每个候选交给未参与猎杀的新验证者,验证者必须重新阅读每条引用的源码位置并独立复现决定性检查;needs_validation只有在独立建立完整路径与有界观察结果后才能晋升为confirmed,被源码驳斥的候选则标记rejected。
  4. Phase 4–6 结构化输出与报告:所有终态记录写入findings.json,由 validate-findings.cjs 与 validate-coverage-ledger.cjs 校验,最终导出 REPORT.md 等目标中立报告。

严重度校准同样适用于本领域:SKILL.md 的锚点中,high对应"完全击败明确安全控制并产生真实后果",例如跨租户读写;如果无法说明具体损害,严重度应低于直觉判断。消息系统审计中最常见的"看起来严重实则未证实"场景——例如"理论上的乱序投递"——恰恰是第 3 条验证规则要拦截的对象:没有投递保证与本地复现,就只能停留在needs_validation。

实战要点速查

  • 启用判断:目标含 gRPC/GraphQL 传输/Cap'n Proto/Thrift/Protobuf/自定义二进制协议/流式 RPC/Webhook/Broker/队列/Pub/Sub/事件总线 → 选择本 Companion,并按 README.md 的安装方式(npx skills add ... --skill security-audit)随技能一并加载。
  • 强制注入:Core discipline、选中的攻击类小节、Universal moves、Validation rules必须逐字进入猎手提示词,不得只发块名。
  • 证据分界:仓库内源码完整路径 + 有界本地生产者/消费者测试 →confirmed;Broker ACL、服务网格身份、主题挂载、兼容性行为等仓库外事实 →needs_validation+ 确切缺失事实 + 安全验证计划。
  • 贯穿原则:通道认证 ≠ 应用授权;schema 校验 ≠ 来源/权限/排序/取值可信;payload 内租户文本 ≠ 隔离;安全策略必须在传输形态(流式/转码/重试/死信)变化后依然成立。
  • AI 技能
  • 应用安全

【免费下载链接】security-audit-skill

A coding-agent skill for multi-phase security audits with independently verified, machine-readable findings

项目地址:https://gitcode.com/GitHub_Trending/se/security-audit-skill
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询