区块链中文技术社区

Solidity进阶之静态分析

静态分析是相对容易掌握的工具,对开发复杂的Defi应用非常有帮助。

简介

合约的安全性自动化检测有静态分析、动态分析和形式化验证。静态分析不执行合约代码,通过对合约代码做模式匹配或者语义分析来检测漏洞。动态分析需要执行合约,通过大量的模糊测试来观察合约的状态是否会出现问题。形式化验证是将合约的业务逻辑用数学表达式来描述,只要证明数学表达式是正确的,则合约的业务逻辑也是正确的(不代表合约的实现没有问题)。

静态分析的优点是使用简单,速度快,但只能检测已知的安全漏洞。动态分析能检测出未知的安全问题,但是成本高、速度慢。形式化验证的使用范围窄,比较适用于一些公共库合约。

开发者对合约做静态分析是最基本的要求,使用静态分析工具可以快速检测是否存在一些常见的漏洞,比如:

但静态分析工具不能检测出跟业务逻辑特定相关的问题,还需要开发人员通过自检去做人工静态分析。

Solhint

Solhint能提供一些代码规范和安全检查,一些推荐的代码规范比如:

Solhint的能力较弱,只能做到语法层面的一些检查,但对规范代码比较有用。

Semgrep

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的功能包括:

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的业务逻辑比较复杂的时候,审计机构不一定能精确地理解每一个业务逻辑。

转载自:https://learnblockchain.cn/article/4270

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »