Details:
The inherit()
function is designed to enable beneficiaries to reclaim control of the contract after a period of inactivity. However, the function does not verify that the caller is actually one of the beneficiaries. In the case where there is exactly one beneficiary, the function sets owner = msg.sender
without checking if msg.sender
is the designated beneficiary. Even when there are multiple beneficiaries, while the function only sets the isInherited
flag, it still lacks any authentication to ensure that only authorized beneficiaries can trigger the inheritance process.
Root Cause:
The root cause is the absence of a validation check (or modifier) within the inherit()
function to confirm that the caller is a listed beneficiary. The function solely relies on a time check and the number of beneficiaries, which is insufficient to prevent unauthorized access.
Impact:
An attacker could exploit this vulnerability by calling the inherit()
function after the inactivity period, especially in a single beneficiary scenario, to illegitimately become the owner. Once ownership is transferred, the attacker could execute owner-only functions (such as transferring assets), resulting in potential theft of contract funds.
Recommendation:
Implement an explicit check within the inherit()
function to ensure that msg.sender
is a valid beneficiary. For example, add a verification step (or use an appropriate modifier) that confirms the caller's address is present in the beneficiaries list before allowing the inheritance logic to proceed. Additionally, consider splitting the logic between the single beneficiary and multiple beneficiary scenarios to handle each case securely.
Proof of Concept:
Set up the contract with exactly one beneficiary.
After the TIMELOCK
period has elapsed, an attacker (whose address is not the designated beneficiary) calls the inherit()
function.
Since the function does not verify caller eligibility, the condition beneficiaries.length == 1
is met, and the contract sets owner = msg.sender
.
The attacker now becomes the owner and can call functions restricted to the owner, potentially draining the contract's funds.
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.