Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
集成与开发阅读约 11 分钟

Cyfrin 安全工具:智能合约审计的实用工作流程

一套可复现的工作流程,使用 Cyfrin 的开源安全工具、审计资源和教育平台,为智能合约代码库做好审查准备。

TL;DR

Cyfrin 是一家区块链安全公司,其公开业务涵盖智能合约审计、Aderyn 静态分析器、Solodit 审计报告聚合器、CodeHawks 竞争性审计平台以及 Updraft 教育平台。本文将上述产品视为一个可复现的审计前工作流程的组成部分,而非品牌概述。你将设置静态分析、将发现映射到检查清单、交叉引用历史报告,并通过 RPC 端点对照实时链验证已部署行为。目标是让代码库在到达人工审计员手中时,琐碎问题更少、文档更完善。

范围与 Cyfrin 式审查背后的思维模型

Cyfrin 的公开资料描述了一个由四层构建的安全栈:人工智能合约审计、通过 Aderyn 进行的自动化静态分析、通过 Solodit 的聚合发现数据库,以及通过 Updraft 和 CodeHawks 的开发者教育。理解这个栈的有用方式是将它视为一个漏斗。自动化工具和历史发现消除低严重性噪音;竞争性审计和教育培养审查者的直觉;人工审查将宝贵的人力注意力集中在逻辑、经济模型和访问控制上。

本文涵盖你可以在聘请任何审计员之前自行运行的自动化和参考层。它不声称能复现付费的 Cyfrin 审计,也不断言 Cyfrin 支持哪些网络或服务超出其公开仓库和网站所述的范围。在需要具体 RPC 端点选择时,请使用 RPC 端点指南 或向 RPC Assistant 询问提供商推荐,而不是从本页硬编码端点。

  • 已记录的行为:Aderyn 是一个用 Rust 编写的 Solidity 静态分析器,在 Cyfrin GitHub 组织下以 GPL-3.0 发布。
  • 已记录的行为:Solodit 聚合智能合约审计发现;CodeHawks 托管竞争性审计;Updraft 托管开发者和安全课程。
  • 建议:在请求报价之前运行静态分析和清单审查,因为它减少了人工审查者必须分类的表面。

先决条件与假设

该工作流程假设一个使用 Hardhat 或 Foundry 的 Solidity 项目,已提交锁文件,本地有 Node.js 或 Rust 工具链,并且对目标网络的公共或私有 RPC 端点有读取权限。你需要仓库写入权限来添加 CI 作业,以及一个将生成的报告存储为构建产物的位置。

运行 Aderyn 或阅读公开审计报告不需要 Cyfrin 账户。付费审计服务、认证课程以及某些平台功能是独立的商业产品;请将其可用性视为需要直接向供应商确认的事项,而不是从本文假设。

安装并运行 Aderyn 静态分析

Aderyn 以 Rust 二进制文件分发,可通过 Cargo 或发布二进制安装。对已编译项目运行它会生成检测器命中的 Markdown 或 JSON 报告。首次运行通常噪音较多;价值在于对每个检测器类别进行一次分类,然后将该分类编码为基线,以便后续运行只暴露新发现。

以下命令是一个可运行的起点。将项目路径替换为你的仓库根目录,并将报告保存在源代码树之外,以免被意外提交。

cargo install aderyn
cd /path/to/your-solidity-project
aderyn . --output report.md
# JSON output for CI ingestion
aderyn . --output report.json --output-format json
# Fail the build only on high-severity detectors (check --help for exact flags in your version)
aderyn . --output report.json --output-format json --fail-on high

将发现映射到审计检查清单

Cyfrin 发布了一个聚合审计检查清单仓库,按类别(如访问控制、算术、外部调用和预言机使用)对常见漏洞类别进行分组。与其从头到尾阅读,不如将每个 Aderyn 检测器命中映射到检查清单条目,并记录该发现是真实阳性、假阳性还是已接受风险并附书面理由。

这个映射步骤是大部分价值产生的地方。它将原始工具报告转换为人工审查者可以浏览的审计就绪文档。将映射存储在仓库中,例如 security/triage.md,以便在团队变动后保留。

  • 真实阳性:修复代码并添加一个在修复前会失败的回归测试。
  • 假阳性:记录使检测器不适用的不变量。
  • 已接受风险:记录接受的所有者、理由和到期日期。

使用 Solodit 交叉引用历史发现

Solodit 聚合来自许多公开审计报告的发现,这使得它有助于回答一个狭窄的问题:这个确切的模式之前是否被利用或标记过,以及是如何修复的?按协议类型和具体函数形态搜索,而不是仅按关键词搜索,因为通用术语会返回太多噪音。

将 Solodit 结果视为现有技术,而不是你的代码安全的证明。出现在另一个协议报告中的发现可能不适用于你的架构,而没有匹配的发现并不能说明你的代码没有问题。此步骤的正确输出是一个需要手动验证的候选问题简短列表,每个问题都链接到其来源报告。

对照实时链验证已部署行为

静态分析无法看到已部署状态。在审计之前,确认你分析的字节码与已部署的匹配,并且特权角色按文档配置。一个通过 RPC 端点读取角色分配和关键参数的小脚本可以捕获任何源代码级工具都无法发现的配置漂移。

以下示例使用 ethers.js 并读取角色常量和所有者地址。将 RPC_URL、CONTRACT_ADDRESS 和 ABI 替换为你的部署值。关于跨网络的提供商选择,请参阅 多链 RPC 端点 和 API 服务概述。

import { ethers } from "ethers";

const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const address = process.env.CONTRACT_ADDRESS;
const abi = [
  "function owner() view returns (address)",
  "function hasRole(bytes32 role, address account) view returns (bool)",
  "function DEFAULT_ADMIN_ROLE() view returns (bytes32)"
];

const contract = new ethers.Contract(address, abi, provider);
const [owner, adminRole] = await Promise.all([
  contract.owner(),
  contract.DEFAULT_ADMIN_ROLE()
]);
const ownerIsAdmin = await contract.hasRole(adminRole, owner);

console.log({ address, owner, ownerIsAdmin });
if (!ownerIsAdmin) {
  console.warn("Owner does not hold DEFAULT_ADMIN_ROLE; confirm this is intentional.");
}

预期验证结果及如何记录

成功的审计前检查会产生四个产物:Aderyn 报告、每个检测器类别都已解决的分类文档、带链接的 Solodit 交叉引用列表,以及来自 RPC 脚本的部署状态快照。将提交哈希、工具版本和区块号与每个产物一起记录,以便结果可复现。

在仓库中使用如下结果表。不要从其他项目复制数字;从你自己的运行中填写每个单元格。该表是模板,不是基准。

  • | 产物 | 命令或来源 | 提交 / 区块 | 审查者 | 状态 |
  • | Aderyn 报告 | aderyn . --output report.json | <commit> | <name> | <open/closed> |
  • | 分类文档 | security/triage.md | <commit> | <name> | <open/closed> |
  • | Solodit 交叉引用 | 手动搜索日志 | 不适用 | <name> | <open/closed> |
  • | 部署快照 | RPC 脚本输出 | <block> | <name> | <open/closed> |

将工作流程添加到 CI

最常见的失败模式是一次性分析,之后不再重新运行。将 Aderyn 接入 CI,以便每个拉取请求都生成新报告,并将其与默认分支的基线进行差异比较。一个简单的方法是将 JSON 报告上传为产物,并运行一个小脚本按严重性比较检测器计数。

起初保持 CI 作业非阻塞,然后在团队分类后将特定检测器提升为阻塞。第一天就对完整检测器集进行阻塞通常会导致开发者完全绕过检查。

# .github/workflows/security.yml (excerpt)
name: security
on: [pull_request]
jobs:
  aderyn:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - run: cargo install aderyn
      - run: aderyn . --output report.json --output-format json
      - uses: actions/upload-artifact@v4
        with:
          name: aderyn-report
          path: report.json

常见故障排除

静态分析器以可预测的方式失败。大多数假阴性来自不完整的编译,大多数假阳性来自无法看到跨合约不变量的检测器。首先解决编译问题,因为无法干净构建的项目会产生误导性的小报告。

RPC 脚本因另一组原因失败:速率限制、错误的链 ID 以及升级后的 ABI 不匹配。在信任任何读取结果之前,记录提供商返回的链 ID 并将其与预期值进行比较。

  • Aderyn 报告为空或很小:确认项目编译通过,并且路径参数指向源代码根目录,而不是仓库根目录。
  • 对生成或供应商代码的检测器命中:明确排除这些路径,而不是忽略整个检测器。
  • RPC 脚本返回 null:验证 ABI 与已部署实现匹配,尤其是在代理后面。
  • 间歇性 RPC 超时:迁移到专用端点;请参阅 专用节点 和 RPC 定价。

局限性与权衡

自动化工具覆盖了真实漏洞类别的一小部分。逻辑错误、经济操纵、预言机设计缺陷和治理攻击通常需要人工审查,并且往往需要协议特定的模拟。Aderyn 及类似分析器最好被理解为保护审计员注意力的过滤器,而不是其替代品。

还有维护成本。检测器基线随着工具更新而漂移,检查清单会过时,CI 作业会积累例外。每季度预算时间重新分类基线并移除不再适用的抑制。如果你的团队无法维持这种节奏,一个实际运行的较窄工作流程比一个被放弃的全面工作流程更好。

迈向审计服务的下一步

一旦四个产物存在且 CI 通过,你就有了一个可辩护的起点,可以用于付费审查或 CodeHawks 上的竞争性审计。准备一份简短的架构说明,涵盖信任假设、特权角色、升级路径和外部依赖,因为这些是人工审查花费最多时间的领域。

对于同时运营基础设施的团队,在审计窗口之前验证用于部署和监控的 RPC 层是否稳定;在实时审查期间不可靠的端点会浪费审查者的时间。通过 OnFinality 网络 和 RPC 端点指南 比较选项,并在需要针对特定链的直接提供商推荐时使用 RPC Assistant。

永远不用担心基础设施

OnFinality 消除了 DevOps 的繁重工作,让您能够更聪明、更快地构建。

开始