自己破壊関数 selfdestruct は、スマートコントラクトにおける潜在的な危険な機能であり、ハッカーはそれを悪意のある攻撃に利用するためにさまざまな手段を用いることができます。この記事では、selfdestruct 攻撃方法と、このような攻撃からのセキュリティコーディングによる防御方法をコードの例を通じて分析します。
攻撃者は、対象のコントラクトの selfdestruct 関数を呼び出すことでコントラクトを破壊することができます。例えば:
contract Target {
address owner;
function selfDestruct() public {
require(msg.sender == owner);
selfdestruct(owner);
}
}
contract Attacker {
function attack(Target target) public {
target.selfDestruct();
}
}
上記の例では、攻撃者は公開された selfDestruct 関数を呼び出し、owner の権限を持っていれば Target コントラクトを削除することができます。
もう一つのシナリオは、攻撃者が継承を通じて selfdestruct へのアクセス権を取得することです。例えば:
contract Base {
function selfDestruct() internal {
selfdestruct(msg.sender);
}
}
// 悪意のある継承
contract Attacker is Base {
function attack() public {
selfDestruct();
}
}
解決策
自己破壊関数にアクセス制御を追加し、所有者のみが呼び出せるようにする
公開可能な自己破壊関数を設定せず、悪意のあるコントラクトに継承されるのを避ける
危険な関数を内部関数 internal に設定する