The InheritanceManager::inherit()
function contains a critical vulnerability that allows any user, not just the designated beneficiary, to become the owner of the contract when there is a single beneficiary. The function fails to verify that the caller (msg.sender) is actually the beneficiary listed in the beneficiaries array.
The function only checks:
That the inactivity period has passed (block.timestamp < getDeadline()
)
That there is exactly one beneficiary (beneficiaries.length == 1
)
It then assigns ownership directly to msg.sender
without verifying that this caller is actually the beneficiary listed in beneficiaries
array.
Any external attacker can monitor contracts with a single beneficiary, wait for the inactivity period to elapse, and then call inherit()
to steal ownership of the contract.
Once an attacker becomes the owner, the legitimate beneficiary loses their inheritance rights and can no longer claim the assets they were entitled to.
The new malicious owner can drain all ETH, ERC20 tokens, and NFTs from the contract using the owner-only functions like sendERC20(), sendETH(), and contractInteractions().
Add a check to verify that the caller is the actual beneficiary before transferring ownership
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.