什么是绕过 EOA 检查?
许多 DeFi 合约只允许 EOA 进行关键操作。合约地址不可调用。这是通过检查 msg.sender 实现的。但攻击者可以在自己的恶意合约中,使用 EOS 或 delegatecall 等方式伪造 msg.sender 为一个 EOA 地址,就可以绕过检查。
防止绕过 EOA 检查的方法:
不仅检查 msg.sender, 还检查 tx.origin, 以确保调用者为 EOA。
使用状态变量在用户首次调用时记录 EOA, 后续调用强制使用 recordedEOA。
在安全的接口合约中进行 EOA 检查,用户只能通过该接口合约调用。
使用 OpenZeppelin 的 EOAChecker 等审计过的安全库。
代码示例:
// Also check tx.origin
require(msg.sender == tx.origin, "Not EOA");
// Record EOA on first call
address public userEOA;
function initEOA() external {
require(userEOA == address(0), "Already initialized");
userEOA = msg.sender;
}
function criticalFunc() external {
require(msg.sender == userEOA, "Only EOA can call");
// Function logic
}