sharthak18/SELF-Smart-Contract-Auditing-Tool

GitHub: sharthak18/SELF-Smart-Contract-Auditing-Tool

SELF 是一款本地确定性离线优先的智能合约安全审计分类工具,通过无编译器的解析引擎在人工审计前快速定位潜在漏洞并生成证明义务。

Stars: 1 | Forks: 0

# SELF — Smart Contract Exploit & Logic Finder [![Python](https://img.shields.io/badge/Python-3.8%2B-blue)](https://python.org) [![Version](https://img.shields.io/badge/Version-2.3.0-red)](VERSION) [![License](https://img.shields.io/badge/License-MIT-green)](LICENSE) [![Offline](https://img.shields.io/badge/Scans-Offline-blueviolet)](SECURITY.md) [![Repo](https://img.shields.io/badge/Repo-GitHub-black)](https://github.com/sharthak18/SELF-Smart-Contract-Auditing-Tool) SELF 是一个**本地、确定性、离线优先**的智能合约审计工具,支持 Solidity、Vyper、Huff、Rust/Anchor 和 Move。它的设计初衷是作为安全研究人员在打开 Foundry 测试、Echidna 活动、Slither 运行或进行人工审计之前进行的第一道扫描。 SELF 提供: - 一个确定性的、由解析器支持的检测器引擎,**无需** Solidity 或 Rust 编译器,无需 RPC,无需云端 LLM,且无需网络访问即可运行。 - 每个 detector ID 与硬编码的**深度审查配置文件**之间的严格一对一映射,其中包含了人类审计员必须为该发现建立的证明义务。 - 一个**项目语义图**,用于解析跨文件的 import、inheritance、modifier guard、内部调用、底层调用和写入操作,然后在出现跨合约风险时发出项目级别的发现(`PROJECT-ACCESS-001`, `PROJECT-PROXY-001`, `PROJECT-REENTRANCY-001`, `PROJECT-AUTH-001`, `PROJECT-ORACLE-001`, `PROJECT-UNRESOLVED-001`)。 - 一个**本地持久化反馈存储**(`~/.self-auditor/feedback.sqlite3`),具有基于指纹范围的抑制功能:更改源代码或使用新版本的规则会自动重新显示该发现。 - 一个**确定性校准语料库**(`self calibrate`),生成每个检测器的精确度、召回率和误报率,以便检测器表可以像任何其他基准测试一样进行审计。 - 一个隔离的、**仅包含元数据的签名清单更新器**(`self update`),从 OWASP Smart Contract Security、OpenZeppelin、Vyper、GHSA 和 NVD 拉取锁定的安全公告元数据。下载的任何内容都不会被执行;也不会静默更改任何检测器。 - 一份 **X 射线预审计报告**(`self --xray`),无需编译任何内容即可映射出入口点、状态写入、modifier、外部调用和 NatSpec 谓词。 - 一个**结构化模糊测试器**(`self --fuzz`),对解析后的合约结构运行基于 Hypothesis 的属性测试,以及一个建模的状态机序列模糊测试器。 - 一个 **PoC harness 生成器**(`self --poc`),为每个触发的漏洞类检测器输出可运行的 Foundry 测试文件,输出路径仅限于扫描目标目录。 SELF **不**声称可以取代人工审计。它是一个分类工具。它回答的问题是“哪些代码行值得仔细查看,以及人类在宣布它们安全之前必须证明什么?”。它可以通过校准和显式反馈将误报降至零;但它永远无法达到绝对的零误报。 ## 目录 1. [安装说明](#install) 2. [快速开始](#quickstart) 3. [命令参考](#command-reference) 4. [输出格式](#output-formats) 5. [检测模型](#detection-model) 6. [项目语义图](#project-semantic-graph) 7. [反馈存储](#feedback-store) 8. [校准](#calibration) 9. [公告更新器](#advisory-updater) 10. [X 射线预审计](#x-ray-pre-audit) 11. [模糊测试](#fuzzing) 12. [PoC 生成](#poc-generation) 13. [自定义规则](#custom-rules) 14. [配置与存储](#configuration-and-storage) 15. [退出码](#exit-codes) 16. [CI 集成](#ci-integration) 17. [限制与诚实的边界](#limits-and-honest-boundaries) 18. [贡献指南](#contributing) 19. [许可证](#license) ## 安装说明 ``` git clone https://github.com/sharthak18/SELF-Smart-Contract-Auditing-Tool.git cd SELF-Smart-Contract-Auditing-Tool python3 -m pip install -e . ``` 验证: ``` self --version # 2.3.0 self --list-detectors # full detector catalog self --knowledge-status # OWASP coverage + knowledge sources ``` 可选,仅当您打算使用结构化模糊测试器时需要: ``` python3 -m pip install hypothesis ``` `hypothesis` 是唯一的可选运行时依赖项。执行 `self --fuzz` 时需要它;不带 `--fuzz` 的扫描无需它也可正常工作。 ## 快速开始 ``` # Scan a directory or a single file. Exit code reflects severity. self . # Generate a Markdown report + JSON sidecar. self src/Vault.sol -o reports/vault.md --json # Project semantic graph (human-readable Markdown). self graph . # Project semantic graph (canonical JSON, for tooling). self graph . --json --output reports/graph.json # Pre-audit X-ray report alongside the normal findings. self . --xray --xray-output reports/xray.md # Property-based fuzzing on parsed structure. self . --fuzz # Generate Foundry PoC harnesses for every exploit-class finding. self . --poc --poc-dir poc/ # Run the deterministic calibration corpus. self calibrate # Pull the latest pinned advisory metadata. self update --manifest-url https://scs.owasp.org/feed.json # List, add, export, import local feedback entries. self feedback list . self feedback add . --finding sf_xxx --type false_positive --reason "uses SafeERC20" self feedback export ./feedback.json self feedback import ./feedback.json ``` 除了 `self update` 和 `self intelligence rollback` 外,所有命令均无需网络访问即可运行。请参阅 [SECURITY.md](SECURITY.md)。 ## 命令参考 ``` self TARGET # scan self [TARGET] --list-detectors # catalog self [TARGET] --knowledge-status # knowledge provenance self graph TARGET [--json] [-o FILE] # project semantic graph self update --manifest-url URL [--dry-run] # pull advisory metadata self intelligence status # list installed snapshots self intelligence rollback SNAPSHOT_ID # activate a previous snapshot self feedback add TARGET --finding FP --type {confirmed|false_positive|accepted_risk|fixed} --reason "..." self feedback list TARGET [--include-inactive] self feedback remove FEEDBACK_ID self feedback export FILE # write local store as JSON self feedback import FILE [--replace] # merge or replace local store self calibrate [--root DIR] [--json] # confusion-matrix report ``` ### 扫描参数 | 参数 | 描述 | |---|---| | `-s`, `--severity` | 报告的最低严重级别:`critical|high|medium|low|info`。 | | `-o`, `--output` | Markdown 报告路径。默认:目标旁边的 `self-report.md`。 | | `--json` | 同时写入 `self-report.json`。 | | `-l`, `--lang` | 强制指定语言(`solidity|vyper|huff|rust|move|typescript`)。 | | `--no-info` | 丢弃 `INFO` 级别的发现。 | | `--quiet` | 隐藏横幅和进度信息;仅打印摘要。 | | `--no-docs` | 跳过文档/NatSpec 上下文收集。 | | `--show-suppressed` | 在报告中包含已抑制的发现。 | | `--trust-doc-suppressions` | **不安全。** 允许 README / NatSpec 声明将发现标记为已抑制。默认关闭。 | | `--xray` | 写入预审计 X 射线报告。 | | `--xray-output` | X 射线报告路径。默认:目标旁边的 `self-xray.md`。 | | `--poc` | 为每个漏洞类的发现生成 Foundry PoC harness。 | | `--poc-dir` | PoC 的输出目录(必须是扫描目标下的相对路径)。默认:`poc/`。 | | `--fuzz` | 扫描后运行基于 Hypothesis 的模糊测试。 | | `--fuzz-mode` | `stateless`、`stateful` 或 `both`(默认)。 | | `--fuzz-iters` | 每个(目标,不变量)的最大 Hypothesis 示例数。默认:`32`。 | | `--fuzz-seqs` | 用于有状态模糊测试的操作序列数。默认:`32`。 | | `--fuzz-seq-len` | 最大序列长度。默认:`6`。 | | `--fuzz-seed` | 固定 RNG 以保证可复现性。 | 来自本地反馈存储的抑制默认是**关闭**的。要应用它们,请在扫描中传入运行时参数(参阅 [反馈存储](#feedback-store)),或者如果您构建的 SELF 暴露了该功能,则运行 `self --apply-suppressions`;系统会记录每次抑制的 catalog/rule-version,因此规则版本更新或源代码编辑会自动重新显示该发现。 ## 输出格式 ### 终端摘要 ``` SELF v2.3.0 scan of /home/auditor/repo CRITICAL findings : 1 HIGH findings : 4 MEDIUM findings : 9 LOW findings : 13 INFO findings : 6 suppressed by docs : 2 fuzz findings : 1 exit code : 2 (>= 1 critical) ``` ### Markdown 报告 Markdown 报告包含: - 一份执行摘要表。 - 一份发现表,包含 `id`、严重性、置信度、位置、代码片段、 审查状态(`STATIC_MATCH | CONTEXT_REQUIRED | MANUAL_PROOF | INFORMATIONAL`)、证明义务以及回归测试配方。 - 一份已抑制发现的附录(当开启 `--show-suppressed` 时)。 - 可选的文档信号部分。 - 可选的 X 射线和模糊测试子章节。 ### JSON 报告 ``` { "version": "2.3.0", "target": "/home/auditor/repo", "framework": "foundry", "project_fingerprint": "pf_…", "issues": [ { "id": "SOL-CRIT-001", "severity": "CRITICAL", "confidence": "HIGH", "title": "Reentrancy in withdraw()", "file": "src/Vault.sol", "line": 42, "snippet": "(bool ok,) = msg.sender.call{value: bal}(\"\");", "description": "…", "exploit_scenario": "…", "remediation": "…", "evidence_paths": [{"file": "src/Vault.sol", "start_line": 42, "end_line": 48, "text_hash": "sh_…", "relation": "writes"}], "suppression_state": "none", "review_status": "CONTEXT_REQUIRED", "proof_obligation": "…", "regression_recipe": "forge test --match-test reentrancy" } ] } ``` ## 检测模型 SELF 结合了五个检测层: 1. **正则表达式模式匹配**,用于语法不变量(重入 guard、 底层调用形状、签名重放面等)。 2. **轻量级的、去除注释的解析器**,适用于每种支持的语言,可以生成合约、函数、modifier、状态变量、事件、modifier、NatSpec 和 assembly 块。请参阅 `self_tool/parsers/`。 3. **项目语义图**,用于合并跨文件的每个文件的事实,并解析 import、inheritance、modifier guard、内部调用、底层调用和写入操作。 4. **项目级检测器**,当图的边跨越多个合约时发出发现(`PROJECT-*`)。 5. **漏洞利用语料库**(`self_tool/knowledge/exploits/exploits.json`),这是一个真实世界漏洞利用的 JSON 目录,会在启动时编译为检测器。向 `exploits.json` 添加新条目就等于教导了审计员。 每个 detector ID 都在 `self_tool/core/builtin_reviewer.py` 中与硬编码的审查配置文件配对。如果检测器未配对或配置文件孤立,启动将失败。`self --list-detectors` 表是权威的事实来源。 ### 支持的语言 | 语言 | 单文件 | 项目级 | 备注 | |---|---|---|---| | Solidity | 是 | 是 | 重入、访问控制、底层调用、签名、proxy init、oracle、算术、tokens、DoS、AMM/借贷/跨链桥/质押 | | Vyper | 是 | — | raw_call、send、storage layout、默认可见性、重入 | | Huff | 是 | — | macros、opcodes | | Rust / Anchor | 是 | — | 缺少 signer、owner、任意 CPI、PDA canonical bump、未检查的算术、stale account read、重复的 mutable account、损坏的 `has_one`、账户生命周期、token 与 Token-2022 混淆、可伪造的 sysvar | | Move | 是 | — | capability、signer、resource 不变量 | | TypeScript | 扫描器匹配 | — | 保留给 Hardhat 脚本使用(尚无检测器) | Cairo (Starknet)、Stylus (Arbitrum)、Sway (Fuel) 和 Tact (TON) 尚未支持。欢迎贡献代码。 ## 项目语义图 ``` self graph . self graph . --json --output graph.json ``` 该图是根据扫描目标中每个受支持文件的解析器事实确定性构建的。它包含: - **节点**:文件、合约、interface、library、abstract contract、函数、modifier、状态变量。 - **边**:`imports`、`inherits`、`implements`、`calls_internal`、 `calls_external`、`delegatecall`、`reads`、`writes`、`guards`、 `uses_library`、`declared_in`。 - **未解析的边**:构建器无法闭合的边(remapping 下的跨文件 import、library 调用附加、通过 interface 变量的动态 dispatch)。这些流向 `PROJECT-UNRESOLVED-001` 而不是靠猜测得出。 项目指纹是 `(framework, sorted node ids, sorted edge kinds)` 的规范 SHA-256。两个相同的项目会产生相同的指纹;重命名文件或拆分合约会产生新的指纹并重新显示之前被抑制的发现。 ## 反馈存储 本地、仅追加、可逆。存储于 `~/.self-auditor/feedback.sqlite3`。 ``` # Add a suppression. --finding is the semantic_fingerprint printed by the # JSON report or `self graph . --json` output. self feedback add . --finding sf_xxx \ --type false_positive \ --reason "uses SafeERC20.transfer (reentrancy not reachable)" # List current entries for a target. self feedback list . # Export / import for sharing across a research team. self feedback export ./team-feedback.json self feedback import ./team-feedback.json --replace ``` 处置方式: - `confirmed` — 添加注释,从不抑制。 - `false_positive` — 仅在开启 `--apply-suppressions` 时抑制。 - `accepted_risk` — 附带明确理由抑制,在 `--show-suppressed` 下可见。 - `fixed` — 添加注释。 抑制要求精确匹配 `(project_fingerprint, detector_id, semantic_fingerprint, source_hash, rule_version)`。更改源代码或使用新版本的规则会自动重新显示该发现。每次更改都会记录到 `~/.self-auditor/audit.log.jsonl` 中。 ## 校准 ``` self calibrate # Markdown confusion matrix self calibrate --json # machine-readable self calibrate --root tests/fixtures/calibration ``` SELF 在 `tests/fixtures/calibration/{positive,negative}/` 下内置了一个确定性校准语料库。每个 fixture 都是一个微型合约,恰好触发(或不触发)一个检测器。运行器会报告每个检测器的精确度、召回率、误报率、置信度校准、fixture 覆盖率和未解析边的比率。 候选规则位于 `self_tool/knowledge/rules/candidates/` 下,在通过校准阈值之前,它们被排除在生产环境之外。任何候选规则都不会仅根据反馈而被静默地从生产环境中移除。 ## 公告更新器 ``` self update --manifest-url https://scs.owasp.org/feed.json --dry-run self update --manifest-url https://scs.owasp.org/feed.json self intelligence status self intelligence rollback snap-2026-07-28-001 ``` `self update` 是在正常运行期间唯一会打开网络连接的命令。它: 1. 连接到硬编码白名单中的 HTTPS 主机(OWASP Smart Contract Security、OpenZeppelin、Vyper、GHSA、NVD)。 2. 将响应限制在 2 MB 以内,并使用 15 秒连接 / 30 秒读取超时。 3. 拒绝重定向到非白名单的主机。 4. 在激活任何快照之前,根据清单验证 SHA-256 哈希值。 5. 将快照存储在 `~self-auditor/intelligence//` 中,通过 `latest` 符号链接进行原子激活。 下载的内容**仅作防御性元数据**。它永远不会被执行,永远不会被实例化为 Python,也永远不会静默更改任何检测器。它为校准语料库和经过人工审查的候选队列提供数据来源。 完整的威胁模型请参阅 [SECURITY.md](SECURITY.md)。 ## X 射线预审计 ``` self . --xray self . --xray --xray-output reports/xray.md ``` X 射线报告是一份确定性的、由解析器支持的攻击面映射图。它包括: - 更改状态的 `public` / `external` 入口点。 - `receive()` 和 `fallback()` 入口点。 - 无需许可 / 角色控制 / 仅限 owner 的分类。 - 价值流向、外部调用、状态写入、重入 guard。 - 提取作为不变量候选者的 `require` / `assert` 谓词。 - 模糊测试和不变量测试的姿态。 - 高频更改文件和与安全相关的 git 提交主题。 - 针对访问、经济学、执行、数学和信任缺口的独立审查视角。 这些都是静态的线索。guard 候选者并不能证明协议不变量在跨调用或跨合约时成立。 ## 模糊测试 ``` self . --fuzz self . --fuzz --fuzz-seed 0xC0FFEE self . --fuzz --fuzz-mode stateful --fuzz-seqs 256 --fuzz-seq-len 10 ``` 静态扫描阶段结束后会运行两个模糊测试器: - **Stateless**:对解析后的合约结构进行基于 Hypothesis 的属性测试(数值边界、枚举覆盖率、签名重放)。 - **Stateful**:建模的状态机序列模糊测试器,使用合成的操作序列驱动 X 射线入口点。 模糊测试发现将以 `fuzz-` 为前缀的 `Issue` 对象发出,并具有与静态发现相同的审查路径。固定 RNG 种子以保证可复现性。 ## PoC 生成 ``` self . --poc self . --poc --poc-dir poc/ ``` 对于每个漏洞类的发现(`SOL-CRIT/HIGH-EXPLOIT-*`, `VYP-CRIT/HIGH-EXPLOIT-*`),SELF 会在 `/poc/` 下写入一个可运行的 Foundry 测试 harness。该 harness 断言记录在案的不变量违规行为针对的是一个存根目标;在真正的审计中,请将存根替换为被审计合约的字节码等效物。 `--poc-dir` 必须是扫描目标目录下的相对路径。SELF 拒绝绝对路径或包含 `..` 组件的路径。 ## 自定义规则 在 `self_tool/detectors//` 下放置一个模块。catalog 会发现任何字面意义的 `Issue(...)` 或 `.as_issues(...)` 规则元数据,并将其绑定到 `self_tool/core/builtin_reviewer.py` 中的审查配置文件。系统会执行严格的配对一致性检查。 ``` from self_tool.query import Q from self_tool.core.issue import Severity, Confidence def detect(file_ctx): return ( Q(file_ctx) .functions() .visibility("external", "public") .has_pattern(r"\.call\s*\{") .not_has_pattern(r"nonReentrant") .as_issues( id="CUSTOM-001", title="External call in {fname}()", severity=Severity.HIGH, confidence=Confidence.MEDIUM, description="Review the external-call ordering in {fname}().", exploit_scenario="A callback may observe or modify inconsistent state.", remediation="Apply checks-effects-interactions and a suitable guard.", ) ) ``` 然后注册一个审查配置文件: ``` REVIEW_PROFILES["CUSTOM-001"] = ReviewProfile( lens="external-call-ordering", proof_obligation="Show that every external call in {fname}() is preceded by a state-finalizing write and followed by no further reads of the affected storage.", regression_recipe="forge test --match-contract Vault -vvvv", ) ``` 如果 catalog 和配置文件表之间出现差异,启动将会失败。 ## 配置与存储 | 路径 | 用途 | |---|---| | `~/.self-auditor/feedback.sqlite3` | 本地反馈存储。 | | `~/.self-auditor/audit.log.jsonl` | 仅追加的事件日志(安装、回滚、反馈、抑制)。 | | `~/.self-auditor/intelligence//` | 已安装的安全公告快照。 | | `~/.self-auditor/intelligence/latest` | 活动快照指针(符号链接或文本)。 | 使用 `SELF_DATA_DIR` 覆盖数据目录。 ## 退出码 | 代码 | 含义 | |---:|---| | `0` | 无活动的 Critical 或 High 发现。 | | `1` | 至少有一个活动的 High 发现。 | | `2` | 至少有一个活动的 Critical 发现。 | | `3` | 检测器导入或运行时失败;审计未完成。 | | `4` | 未找到受支持的源文件。 | ## CI 集成 GitHub Actions: ``` name: self on: [push, pull_request] jobs: audit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" - run: python -m pip install -e . - run: self src --severity high --json --quiet ``` `Severity: high` 步骤会在出现 High 或 Critical 发现时导致构建失败。 ## 限制与诚实的边界 - 大多数规则都是启发式的,可能会产生误报。SELF 从校准语料库中报告每个检测器的精确度,并允许人类显式地应用 `false_positive` 和 `accepted_risk` 抑制。**没有任何系统可以保证零误报。** - 正则表达式和轻量级解析不能取代由编译器支持的 AST。Solana/Anchor 语义检查是针对 `#[derive(Accounts)]` 结构体和指令处理器的解析器支持模式运行的;与全文件正则表达式相比,它们提高了精度,但不会执行全程序类型解析。 - 跨合约推理是基于解析器的且相对保守。项目语义图通过确定性的符号索引解析 import、inheritance、library 调用和写入操作,并将未解析的边作为 `PROJECT-UNRESOLVED-001` 发现显示出来。未实现符号执行和跨 crate 的 Rust 编译。 - 业务逻辑和经济学安全需要特定于协议的不变量。 - X 射线状态写入映射器只解析直接写入,而不是任意的继承或过程间效应。 - 新的攻击类别需要维护相应的规则、测试和源代码审查。 SELF 默认是离线的。唯一会打开网络连接的命令是 `self update` 和 `self intelligence rollback`,它们是明确通过选项开启的、仅限 HTTPS、受主机白名单限制、受大小/时间限制并经过内容哈希验证的。 模糊测试阶段是结构化的:对解析后的合约结构进行基于 Hypothesis 的属性测试,以及一个建模的状态机序列模糊测试器。它**不**等同于 Foundry 的 `forge fuzz`、Echidna 或 Mollusk,也不执行任意 EVM 字节码或 Solana BPF 程序。 一次干净的 SELF 扫描是有用的分类信号;它**不能**替代人工的协议不变量审查和顶级的人工审计。 ## 贡献指南 请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。新的检测器必须: 1. 位于 `self_tool/detectors//` 下,并暴露一个 `detect` 函数。 2. 发出带有字面 `id=` 的 `Issue` 记录(以便 catalog 扫描器可以发现它们)。 3. 添加一个匹配的 `REVIEW_PROFILES[id]` 条目,包含真实的证明义务和回归测试配方。 4. 在 `tests/fixtures/calibration/{positive,negative}/` 下提供正面和负面的 fixture。 5. 通过 `self calibrate` 且不标记负面 fixture。 Bug 报告和检测器想法:请提交 issue。 ## 许可证 MIT。请参阅 [LICENSE](LICENSE)。
标签:Python, 云安全监控, 区块链安全, 可视化界面, 无后门, 智能合约, 逆向工具, 静态分析