ETH 강제 전송 - 2
9265 단어 soliditysecuritybestpractice
selfdestruct
에 대해 알아보았고, 어떤 컨트랙트에 강제로 ETH를 보내는 데 사용되는지 알아보았습니다.이제 이 취약점이 무엇인지 이해하기 위해 예를 들어 보겠습니다. 다음 계약을 고려하십시오.
contract Crowdfund {
// this contract only accepts a certain amount of funds
// if someone tries to send an amount that exceeds contract balance more than the limit, tnx fails
// funds are transfered to an address only when contract balance equals fund limit
uint fundLimit = 3 ether;
bool contractOpen = true;
function donate() external payable { // for others to donate eth to this contract
require(contractOpen, "Contract has stopped recieving funds");
require(address(this).balance <= fundLimit, "Can't send specified amount");
// note: we cannot do address(this).balance + msg.value, because address(this).balance already takes msg.value
}
function getBalance() external view returns(uint) { // to get current balance of this contract
return address(this).balance;
}
function sendFunds() external { // to send all collected funds
require(contractOpen, "Contract has stopped recieving funds");
require(address(this).balance == fundLimit, "Fund limit not reached yet");
contractOpen = false; // contract closed
payable(address(0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB)).transfer(address(this).balance);
}
}
이제 다음 시나리오를 고려하십시오.
require(address(this).balance == fundLimit, "Fund limit not reached yet");
함수의 sendFunds()
가 실패하고 수집된 자금을 필요한 수신자에게 보낼 수 없습니다. 취약점이 정확히 무엇인지 파악하셨기를 바랍니다.
공격자 계약을 살펴보겠습니다.
contract Attacker{
fallback() external payable {
}
function attack(address _crowdFund) external {
selfdestruct(payable(_crowdFund));
}
}
지금까지 우리는 이 취약점이 정확히 무엇이며 해커가 이를 악용할 수 있는 방법을 이해했습니다. 이제 그러한 해킹을 피하는 방법을 살펴보겠습니다.
require(address(this).balance == fundLimit, "Fund limit not reached yet");
에require(address(this).balance >= fundLimit, "Fund limit not reached yet");
계약의 sendFunds()
기능에서 Crowdfund
.그러나 그것이 일부 응용 프로그램의 중요한 조건이라면 어떨까요?
address(this)
를 사용하여 자금이를 더 잘 이해하기 위해 다음 계약을 살펴보겠습니다.
contract CrowdFund_safe{
uint fundLimit = 3 ether;
bool contractOpen = true;
uint balance = 0;
function donate() external payable { // for others to donate eth to this contract
require(contractOpen, "Contract has stopped recieving funds");
require(balance + msg.value <= fundLimit, "Can't send specified amount");
balance += msg.value;
}
function getBalance() external view returns(uint) { // to get current balance of this contract
return address(this).balance;
}
function sendFunds() external { // to send all collected funds
require(contractOpen, "Contract has stopped recieving funds");
require(balance == fundLimit, "Fund limit not reached yet");
contractOpen = false; // contract closed
payable(address(0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB)).transfer(balance);
}
}
이제 해커가 이 계약에 ETH를 강제로 보내더라도 상태 변수
balance
가 변경되지 않으므로 계약의 조건에 영향을 미치지 않습니다.따라서 계약은 그러한 공격으로부터 안전합니다.
Reference
이 문제에 관하여(ETH 강제 전송 - 2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/rushanksavant/force-send-eth-2-5b1l텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)