关于 algorand-vulnerability-scanner
Algorand Vulnerability Scanner 是用于审计 Algorand TEAL 和 PyTeal 合约的安全技能。它检查 11 类平台特定漏洞;安装了 Tealer 时也可运行该工具,并按模式报告覆盖情况和发现。
主要功能
- 01识别 TEAL 和 PyTeal 合约文件
- 02检查 11 类 Algorand 漏洞模式
- 03按模式报告覆盖判定及位置
- 04在可用时运行 Tealer
- 05为发现的问题提供修复建议
适用场景
- 01审计 Algorand 状态型应用和智能签名
- 02在正式审计前检查 TEAL 或 PyTeal 代码
- 03验证已报告 Algorand 漏洞的修复
- 04培训团队掌握 Algorand 安全模式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ trailofbits/ skills --skill algorand-vulnerability-scanner安装后在 Claude Code 中输入/algorand-vulnerability-scanner确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlassets/trail-of-bits-mark.svgresources/VULNERABILITY_PATTERNS.md详细介绍
Algorand 漏洞扫描器
1. 目的
系统地扫描 Algorand 智能合约(TEAL 和 PyTeal),检测 Trail of Bits 的“Not So Smart Contracts”数据库中记录的平台特定安全漏洞。此技能针对 Algorand 交易模型特有的 11 种关键漏洞模式。
2. 何时使用此技能
- 审计 Algorand 智能合约(有状态应用或智能签名)
- 审查 TEAL 汇编代码或 PyTeal 代码
- 对 Algorand 项目进行审计前安全评估
- 验证针对已报告 Algorand 漏洞的修复
- 培训团队了解 Algorand 特有的安全模式
3. 平台检测
文件扩展名和标识
- TEAL 文件:
.teal - PyTeal 文件:导入 PyTeal 的
.py文件
语言/框架标记
# PyTeal indicators
from pyteal import *
from algosdk import *
# Common patterns
Txn, Gtxn, Global, InnerTxnBuilder
OnComplete, ApplicationCall, TxnType
@router.method, @Subroutine
项目结构
approval_program.py/clear_program.pycontract.teal/signature.teal- 引用了 Algorand SDK 或 Beaker 框架
工具支持
- Tealer:Trail of Bits 为 Algorand 提供的静态分析器
- 安装:
uv tool install tealer(确保 uv 的工具 bin 目录位于 PATH 中) - 用法:
tealer contract.teal --detect all
4. 此技能的工作方式
调用后,我将:
- 搜索你的代码库,查找 TEAL/PyTeal 文件
- 分析每个文件,检查 11 种漏洞模式
- 报告发现,附上文件引用和严重程度,并在其上方提供一张涵盖所有模式且为每种模式给出判定的覆盖表
- 提供修复方案,处理每个已识别的问题
- 运行 Tealer(如果已安装),进行自动检测
5. 输出示例
发现漏洞时,你会收到类似以下的报告:
=== ALGORAND VULNERABILITY SCAN RESULTS ===
Project: my-algorand-dapp
Files Scanned: 3 (.teal, .py)
Vulnerabilities Found: 2
Coverage: 11/11 patterns reported
1 Rekeying Attack ................... found approval.py:45
2 Unchecked Transaction Fee ......... n/a stateful app, fees paid by sender
3 Closing Account ................... clear Assert(Txn.close_remainder_to() == Global.zero_address())
... one row per pattern, all 11 present ...
---
[CRITICAL] Rekeying Attack
File: contracts/approval.py:45
Pattern: Missing RekeyTo validation
Code:
If(Txn.type_enum() == TxnType.Payment,
Seq([
# Missing: Assert(Txn.rekey_to() == Global.zero_address())
App.globalPut(Bytes("balance"), balance + Txn.amount()),
Approve()
])
)
Issue: The contract doesn't validate the RekeyTo field, allowing attackers
to change account authorization and bypass restrictions.
6. 漏洞模式(11 种模式)
我会检查 Algorand 特有的 11 种关键漏洞模式。有关详细的检测模式、代码示例、缓解措施和测试策略,请参阅 VULNERABILITY_PATTERNS.md。
模式摘要:
- Rekeying 攻击 ⚠️ 严重 - 未检查 RekeyTo 字段
- 未检查交易费用 ⚠️ 高 - 智能签名中未验证费用
- 关闭账户(CloseRemainderTo) ⚠️ 严重 - 未检查 CloseRemainderTo,导致账户资金被转走
- 关闭资产(AssetCloseTo) ⚠️ 严重 - 未检查 AssetCloseTo,导致资产持仓被转走
- 群组大小检查 ⚠️ 高 - 未对原子交易组验证
Global.group_size() - 基于时间的重放攻击 ⚠️ 中 - 未设置租约或轮次范围限制
- 访问控制 ⚠️ 严重 - 更新/删除操作和特权调用未受保护
- 资产 ID 验证 ⚠️ 高 - 资产操作中未验证资产 ID
- 拒绝服务(资产选择加入) ⚠️ 中 - 推送转账会使未选择加入的账户无法使用相关资产
- 内部交易费用 ⚠️ 中 - 未将内部交易费用显式设为 0
- 清除状态交易 ⚠️ 高 - 清除状态程序无法拒绝交易,导致状态不一致
如需查看包含代码示例的完整漏洞模式,请参阅 VULNERABILITY_PATTERNS.md。
7. 扫描工作流
第 1 步:平台识别
- 确认文件扩展名(
.teal、.py) - 识别框架(PyTeal、Beaker、纯 TEAL)
- 确定合约类型(有状态应用或智能签名)
- 定位审批程序和清除状态程序
第 2 步:使用 Tealer 进行静态分析
# Run Tealer on contract
tealer contract.teal --detect all
# Or specific detectors
tealer contract.teal --detect unprotected-rekey,group-size-check,update-application-check
第 3 步:手动排查漏洞
针对上述 11 种漏洞中的每一种:
- 搜索相关交易字段的用法
- 验证是否存在校验逻辑
- 检查是否存在绕过条件
- 验证内部交易处理方式
第 4 步:交易字段验证矩阵
为所有使用的交易类型创建检查清单:
支付交易:
- 已验证 RekeyTo
- 已验证 CloseRemainderTo
- 已验证 Fee(如果是智能签名)
资产转账:
- 已验证资产 ID
- 已验证 AssetCloseTo
- 已验证 RekeyTo
应用调用:
- 已验证 OnComplete
- 已强制执行访问控制
- 已验证组大小
内部交易:
- 已将 Fee 显式设为 0
- RekeyTo 不受用户控制(Teal v6+)
- 已验证所有字段
第 5 步:交易组分析
对于原子交易组:
- 验证
Global.group_size()检查 - 审查绝对索引与相对索引
- 检查重放保护(Lease 字段)
- 验证组中 ApplicationCalls 的 OnComplete 字段
第 6 步:访问控制审查
- 已妥善强制执行创建者/管理员权限
- 已保护更新/删除操作
- 敏感函数已包含授权检查
8. 报告格式
覆盖情况表
报告 §6 中的每种模式,无论是否发现问题。请将此表置于发现项之前,并确保 包含全部 11 行:
| # | 模式 | 判定 | 证据 |
|---|---|---|---|
| 1 | Rekeying 攻击 | found | approval.py:45 -- 支付分支中没有 Txn.rekey_to() 断言 |
| 2 | 未检查交易费用 | ||
| 3 | 关闭账户(CloseRemainderTo) | ||
| 4 | 关闭资产(AssetCloseTo) | ||
| 5 | 组大小检查 | ||
| 6 | 基于时间的重放攻击 | ||
| 7 | 访问控制 | ||
| 8 | 资产 ID 验证 | ||
| 9 | 拒绝服务(资产选择加入) | ||
| 10 | 内部交易费用 | ||
| 11 | 清除状态交易 |
每种判定只能是:
found— 引用file:line,并在下方完整写出发现项。clear— 此模式适用于该合约,且合约已妥善处理。指出你搜索的字段、操作码或检查项,方便读者重复搜索。n/a— 此模式不适用于此处。用一个分句说明原因(“此合约中没有内部交易”)。没有检查不等于n/a。
少于 11 行的表格属于不完整扫描,必须如实报告。Verdict 单元格为空的行也同样不完整:上方第 1 行已填写,用于展示格式;报告完成前,每一行都必须以同样方式填写。11 项 clear 的结果也能为读者提供有用信息。只涵盖四种模式、对其余七种保持沉默的报告,看起来与合约没有问题完全一样,而这正是此表要防止的失误。
发现项模板
## [SEVERITY] Vulnerability Name (e.g., Missing RekeyTo Validation)
**Location**: `contract.teal:45-50` or `approval_program.py:withdraw()`
**Description**:
The contract approves payment transactions without validating the RekeyTo field, allowing an attacker to rekey the account and bypass future authorization checks.
**Vulnerable Code**:
```python
# approval_program.py, line 45
If(Txn.type_enum() == TxnType.Payment,
Approve() # Missing RekeyTo check
)
```
**Attack Scenario**:
1. Attacker submits payment transaction with RekeyTo set to attacker's address
2. Contract approves transaction without checking RekeyTo
3. Account authorization is rekeyed to attacker
4. Attacker gains full control of account
**Recommendation**:
Add explicit validation of the RekeyTo field:
```python
If(And(
Txn.type_enum() == TxnType.Payment,
Txn.rekey_to() == Global.zero_address()
), Approve(), Reject())
```
**References**:
- building-secure-contracts/not-so-smart-contracts/algorand/rekeying
- Tealer detector: `unprotected-rekey`
9. 优先级指南
严重(需要立即修复)
- Rekeying 攻击
- CloseRemainderTo/AssetCloseTo 问题
- 访问控制绕过
高(部署前修复)
- 未检查交易费用
- 资产 ID 验证问题
- 组大小验证
- 清除状态交易检查
中(在审计中处理)
- 内部交易费用问题
- 基于时间的重放攻击
- 通过资产选择加入造成的 DoS
10. 测试建议
必需的单元测试
- 使用 PoC 漏洞利用测试每种漏洞场景
- 验证修复能够防止漏洞利用
- 测试边界情况(组大小 = 0、空地址等)
Tealer 集成
# Add to CI/CD pipeline
tealer approval.teal --detect all --json > tealer-report.json
# Fail build on critical findings
tealer approval.teal --detect all --fail-on critical,high
场景测试
- 提交所有关键字段均经过篡改的交易
- 测试大小异常的原子交易组
- 尝试绕过访问控制
- 验证内部交易费用处理
11. 其他资源
- 构建安全合约:
building-secure-contracts/not-so-smart-contracts/algorand/ - Tealer 文档:https://github.com/crytic/tealer
- Algorand 开发者文档:https://developer.algorand.org/docs/
- PyTeal 文档:https://pyteal.readthedocs.io/
12. 快速参考检查清单
完成 Algorand 审计前,请确认已检查所有项目:
- 已在所有交易类型中验证 RekeyTo
- 已在支付交易中验证 CloseRemainderTo
- 已在资产转账中验证 AssetCloseTo
- 已验证交易费用(智能签名)
- 已验证原子交易的组大小
- 已使用 Lease 字段防止重放(如适用)
- 已对 Update/Delete 操作设置访问控制
- 已在所有资产操作中验证资产 ID
- 资产转账使用拉取模式,避免拒绝服务攻击
- 已将内部交易费用明确设为 0
- 已为 ApplicationCall 交易验证 OnComplete 字段
- 已完成 Tealer 扫描,且没有严重或高危发现
- 单元测试覆盖所有漏洞场景
- 已输出覆盖情况表,包含全部 11 行,且每行均标注
found、clear或n/a,并说明原因
13. 应当驳回的托词
- “合约很小,所以大多数模式显然不适用。” 对谁来说显然?写一句
n/a就能让判断可供审查。沉默不会留下任何记录,读者也无法分辨这是不适用,还是根本没有检查。 - “Tealer 没有报告问题,所以合约是安全的。” Tealer 只覆盖这 11 种模式中的一部分,完全无法检查逻辑层面的模式。工具扫描结果干净,只是其中一项证据,并不能作为对其从未检查过的模式的结论。请说明它覆盖了哪些模式。
- “我检查了这个合约中重要的模式。” 判断哪些模式重要,本身就是扫描工作,而不是开始扫描的前提。应在表格完整后再按严重程度排序,而不是漏掉某些行。
- “没有发现问题,所以没什么可报告的。” 即使扫描未发现问题,也仍然要输出完整的覆盖情况表。该表就是交付成果:它能区分经过检查的合约与只是匆匆看过的合约。
- “PyTeal/Beaker 会处理这个问题。” 请明确指出版本和机制。框架默认设置会随版本变化,而且框架即使在某条调用路径上覆盖了某种模式,也常常不会在其他路径上覆盖。
- “RekeyTo 检查在另一个程序里。” 那就引用它。你认为在其他地方存在的验证,在拿出
file:line之前都只是一个假设;而拆分到多个程序中的合约尤其容易遗漏这类检查。