专栏名称: 看雪学苑
致力于移动与安全研究的开发者社区,看雪学院(kanxue.com)官方微信公众帐号。
目录
相关文章推荐
上海普陀  ·  聚智赋能!2025第四届新耀东方网络安全博览 ... ·  8 小时前  
上海普陀  ·  聚智赋能!2025第四届新耀东方网络安全博览 ... ·  8 小时前  
计算机与网络安全  ·  网络安全资料库 ·  昨天  
51好读  ›  专栏  ›  看雪学苑

使用区间分析识别智能合约中的漏洞

看雪学苑  · 公众号  · 互联网安全  · 2025-05-07 17:59

正文

请到「今天看啥」查看全文



function split(address[] calldata recipients) external payable
{
require(msg.value > 0,"Please provide currency to be split among recipients");
uint amount = msg.value / recipients.length; // problem here if length is 0
for(uint index = 0; index < recipients.length; index++)
{
(bool success,) = payable(recipients[index]).callvalue:amount("");
require(success,"Could not send ether to recipient");
}
}


整数除法余数

这也是许多编程语言中常见的算术问题。Solidity 执行整数除法,这意味着除法操作的结果会被截断。这可能导致忽略除法余数,从而产生逻辑错误。以下代码片段提供一个示例:如果提供的金额不能被接收者的数量整除,那么部分加密货币可能会被锁定在合约中。


function split(address[] calldata recipients) external payable
{
require(recipients.length > 0,"Empty recipients list");
uint amountPerRecipient = msg.value / recipients.length; // remainder ???
require(amountPerRecipient > 0,"Amount must be positive");
for(uint index = 0; index < recipients.length; index++)
{
payable(recipients[index]).transfer(amountPerRecipient);
}
}

未初始化变量

未初始化的变量可能会导致逻辑错误或异常。如果变量未被初始化,根据其类型赋予的默认值很可能不适合该变量的用途。以下代码包含一个依赖于 owner 状态变量的访问修饰符。该变量是私有的,因此无法在合约外部访问或赋值。此外,构造函数中也没有对 owner 进行显式初始化。这会导致变量保持默认值,从而使所有带有 onlyOwner 修饰符的函数无法执行。


address private owner;

modifier onlyOwner() {
require(msg.sender == owner, "Only the owner of the contract has access");
_;
}


用户输入验证

参数验证或“净化”是每个方法开始时必须实现的过程。这确保了方法总是按预期执行。不能信任终端用户总是提供有效参数。如果缺少验证,而用户又不了解,甚至是恶意的,就可能导致关键性错误,从而产生意外结果或完全停止合约的执行。以下示例包含一个内部数组的 getter 方法。用户可以提供未经验证的索引,因此有可能越界访问。


uint256[] private _array= [10, 20, 30, 40, 50];

function getArrayElement(uint256 index) external view returns (uint256)
{
return _array[index];
}


类型不匹配

在 Solidity 中,枚举类型以无符号整数的形式存储。因此,它们可以与 uint 类型的变量进行比较和赋值。然而,这种情况可能很棘手,因为枚举的值域通常远小于无符号整数的值域。如果将一个超过枚举范围的变量赋值给枚举变量,则交易将被回滚。虽然回滚交易被认为是安全的,但这种情况表明合约代码存在逻辑错误,最好避免出现此类问题。


contract UnmatchedType {
enum Options { Candidate1, Candidate2, Candidate3 }
mapping(address => Options) private _votes;
mapping(Options => uint) private _votesCount;
function vote(uint option) external {
_votes[msg.sender] = Options(option);
_votesCount[Options(option)]++;
}
function getStatisticsForOption(uint option) external view returns(uint) {
return _votesCount[Options(option)];
}
}




3

使用专用分析工具检测漏洞


本节简要介绍我们所进行的一些实验结果。 基本上,我们使用了一些工具对智能合约进行分析,以检查它们在第 2 节所示示例中的表现。 我们选择的工具如下所示。







请到「今天看啥」查看全文


推荐文章
计算机与网络安全  ·  网络安全资料库
昨天
晒爱思PsyEyes  ·  人性 | 中国“丑男”是如何炼成的
8 年前