静态分析是相对容易掌握的工具,对开发复杂的Defi应用非常有帮助。
合约的安全性自动化检测有静态分析、动态分析和形式化验证。静态分析不执行合约代码,通过对合约代码做模式匹配或者语义分析来检测漏洞。动态分析需要执行合约,通过大量的模糊测试来观察合约的状态是否会出现问题。形式化验证是将合约的业务逻辑用数学表达式来描述,只要证明数学表达式是正确的,则合约的业务逻辑也是正确的(不代表合约的实现没有问题)。
静态分析的优点是使用简单,速度快,但只能检测已知的安全漏洞。动态分析能检测出未知的安全问题,但是成本高、速度慢。形式化验证的使用范围窄,比较适用于一些公共库合约。
开发者对合约做静态分析是最基本的要求,使用静态分析工具可以快速检测是否存在一些常见的漏洞,比如:
但静态分析工具不能检测出跟业务逻辑特定相关的问题,还需要开发人员通过自检去做人工静态分析。
Solhint能提供一些代码规范和安全检查,一些推荐的代码规范比如:
call
,delegatecall
等底层操作码tx.origin
msg.value
block.number
和block.timestamp
Solhint的能力较弱,只能做到语法层面的一些检查,但对规范代码比较有用。
Semgrep是一个通用型的静态分析工具,支持多种语言,对solidity的支持目前还较弱。Semgrep跟Solhint一样也是采用模式匹配来进行检测,Solhint的规则是内置的,Semgrep能自定义规则。比如下面这个规则compound-sweeptoken-not-restricted
rules:
-
id: compound-sweeptoken-not-restricted
message: function sweepToken is allowed to be called by anyone
metadata:
references:
- https://medium.com/chainsecurity/trueusd-compound-vulnerability-bc5b696d29e2
- https://chainsecurity.com/security-audit/compound-ctoken/
- https://blog.openzeppelin.com/compound-comprehensive-protocol-audit/
- https://etherscan.io/address/0xa035b9e130f2b1aedc733eefb1c67ba4c503491f # Compound
category: access-control
tags:
- compound
- tusd
patterns:
- pattern-inside: |
function sweepToken(...) {
...
}
- pattern: token.transfer(...);
- pattern-not-inside: |
require(msg.sender == admin, "...");
...
languages:
- solidity
severity: WARNING
这个规则专门针对的Compound曾经出现过的TUSD漏洞,由于有很多其它链的项目fork了Compound,因此这个规则可以快速检测出这些项目是否有类似的问题。
Slither的功能包括:
Slither的原理是将Solidty抽象语法树(AST)作为输入:
Solhint和Semgrep都是在语法级别进行规则匹配,相比而言Slither能在语义级别进行分析。Slither也可以通过插件来实现自定义的漏洞检测规则,实现上要比Semgrep这种配置文件的方式复杂点。
相对于自动检测工具而言,开发者的自检能完成更复杂的静态分析。比如
address[] public minters;
function setMinter() external {
minters.push(msg.sender);
}
静态分析工具没法知道修改minters
这个状态变量需要什么权限,因为这属于业务逻辑的范围。再比如
if (a > 100) {
b++;
}
如果开发者误将a >= 100
写成了a > 100
,这种业务逻辑错误静态分析工具也没法处理。
合约的业务逻辑都是主要在接口中实现的,因此接口检查就很重要:
如果接口涉及到Token的转移,则需要的检查有:
对于借贷相关的合约,一般需要使用价格,则需要的检查有:
总之,所有的检查都围绕几个核心:
静态分析是相对容易掌握的工具,对开发复杂的Defi应用非常有帮助。不同的静态分析工具可以结合使用,可以先使用Solhint来规范代码,然后使用Semgrep来识别已知的漏洞,接着使用Slither来识别一些语义级别的问题。
开发者更需要自己检查代码,最好是邀请同行互审。最后还是需要审计机构审计代码,不过也不要迷信审计机构,尤其是当Defi的业务逻辑比较复杂的时候,审计机构不一定能精确地理解每一个业务逻辑。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!