{ 跳到内容 }

安全警报:变量可能在存储中被覆盖

发布于 2016 年 11 月 1 日,作者 Christian Reitwiessner

安全警报

这篇文章最初发布在以太坊博客.

摘要:在某些情况下,变量可能覆盖存储中的其他变量。

受影响的 Solidity 编译器版本:0.1.6 到 0.4.3(包括 0.4.4 预发布版本)

详细描述

小于 256 位的存储变量如果可以容纳,则会打包到同一个 256 位槽中。如果将大于类型允许的值分配给第一个变量,则该值将覆盖第二个变量。

这意味着如果攻击者可以导致第一个变量的值溢出,则可以修改第二个变量。使用算术运算或通过直接从调用数据传递值(调用数据中的值对齐到 32 字节,并且填充既不验证也不强制)来创建第一个变量的溢出是可能的。

仅对状态变量使用下面列出的类型的合约不受影响。数组、映射和结构体(基于以下类型)也不受影响

  • 有符号整数,包括小于 256 位的大小
  • bytesNN 类型,包括小于 256 位的大小
  • 256 位的无符号整数(uint)

小于 256 位的类型在彼此之间从未相邻的合约(注意,基础合约的状态变量会被“拉入”)不受影响。

以太坊多重签名钱包合约不受影响。请注意,地址占用 160 位,因此仅使用地址和 256 位类型的合约是安全的。此外,在实践中,地址和布尔值几乎从未通过算术运算进行操作,因此仅使用地址、布尔值和 256 位类型的合约也应该是安全的。

以下合约可能会受到影响:包含两个或多个连续状态变量的合约,其中它们的总大小小于 256 位,并且第一个状态变量不是有符号整数,也不是 bytesNN 类型。

小于 256 位的类型包括:bool、枚举、uint8、...、uint248、int8、...、int248、address、任何合约类型

建议的操作

  • 使用至少 Solidity 版本 0.4.4(不是预发布或夜间版本)重新编译尚未部署的合约。
  • 停用、提取资金或升级已部署的合约。

此漏洞由 @catageek 发现:https://github.com/ethereum/solidity/issues/1306

上一篇

下一篇

参与进来

GitHub

推特

Mastodon

矩阵

了解更多

博客文档用例贡献关于论坛

2024Solidity 团队

安全策略

行为准则