https://blog.thirdweb.com/vulnerability-report/
ERC-2771 把calldata最后20字节当作_msgSender() 当msg.sender是可信的时,组合上合约自带的multicall(delegatecall给自己)就能出问题
攻击者让可信的forwader发起multicall,这时候只有multicall函数读取的_msgSender()是真的,进入delegatecall里面执行的_msgSender()就是攻击者自己构建的calldata 可以伪造成高权限地址
修复方案就是multicall函数需要重写来带上真正的sender:
ERC-2771 把calldata最后20字节当作_msgSender() 当msg.sender是可信的时,组合上合约自带的multicall(delegatecall给自己)就能出问题
攻击者让可信的forwader发起multicall,这时候只有multicall函数读取的_msgSender()是真的,进入delegatecall里面执行的_msgSender()就是攻击者自己构建的calldata 可以伪造成高权限地址
修复方案就是multicall函数需要重写来带上真正的sender:
function multicall(bytes[] calldata data) external returns (bytes[] memory results) {
results = new bytes[](data.length);
address sender = _msgSender();
bool isForwarder = msg.sender != sender;
for (uint256 i = 0; i < data.length; i++) {
if (isForwarder) {
results[i] = Address.functionDelegateCall(address(this), abi.encodePacked(data[i], sender));
} else {
results[i] = Address.functionDelegateCall(address(this), data[i]);
}
}
return results;
}