tx.origin安全问题总结

2022-11-07 10:09:27 浏览数 (1)

本文作者:小驹[1]

在合约代码中,最常用的是使用 msg.sender 来检查授权,但有时由于有些程序员不熟悉 tx.origin[2] 和 msg.sender 的区别,如果使用了 tx.origin 可能导致合约的安全问题。黑客最典型的攻击场景是利用tx.origin的代码问题常与钓鱼攻击相结合的组合拳的方式进行攻击。

tx.origin 是 Solidity 中的一个全局变量,它返回发送交易的账户地址。

通过调用 tx.origin 来检查授权可能会导致合约受到攻击,因为 tx.origin 返回交易的原始发送者,因为攻击的调用链可能是原始发送者->攻击合约-> 受攻击合约。在受攻击合约中,tx.origin 是原始发送者。

前置知识

EOA 账户和合约账户

以太坊账户分两种,外部账户(EOA)和合约账户(SCA)。

  1. 外部账户由一对公私钥进行管理,账户包含着 Ether 的余额。
  2. 合约账户除了可以含有 Ether 余额外,还拥有一段特定的代码,预先设定代码逻辑在外部账户或其他合约对其合约地址发送消息或发生交易时被调用和处理。

外部账户 EOA

  • 由公私钥对控制
  • 拥有 ether 余额
  • 可以发送交易(transactions)
  • 不包含相关执行代码

合约账户

  • 拥有 ether 余额
  • 含有执行代码
  • 代码仅在该合约地址发生交易或者收到其他合约发送的信息时才会被执行
  • 拥有自己的独立存储状态,且可以调用其他合约

msg.sender 和 tx.origin 的区别

tx.origin:表示最初的调用者,通常取得的是 EOA 的地址。

msg.sender:表示最近的调用者,通常取得是的上级调用者的地址,可以是 EOA 地址,也可以是合约地址。

如果 EOA 用户 A 调用合约 B,合约 B 调用合约 C。那么

  • 在 C 合约中,msg.sender 就是 B 合约的地址,tx.origin 为 A 地址。
  • 在 B 合约中,msg.sender 是 A 地址,tx.origin 也为 A 地址。

通过判断tx.origin==msg.sender来确定调用者是合约还是 EOA 账户。

0 人点赞