The identified vulnerability is located in the verifyCharity
function of the CharityRegistry
smart contract, specifically on Line 22. The issue arises from the use of the admin
address for performing critical operations, such as verifying charities and changing the admin. This introduces a privilege escalation vulnerability that could allow an attacker to take control of the contract and manipulate key functionalities, such as verifying or registering charities.
The vulnerability stems from the fact that the admin
address is hardcoded into the contract, which can be exploited in a specific attack scenario. Additionally, while the contract allows the admin to change the admin address, the check for whether the transaction is coming from the admin is not sufficiently secured in some edge cases.
The root cause of the vulnerability lies in the following code:
The verifyCharity
function uses the msg.sender
to verify if the caller is the current admin
. The admin is set during contract deployment and can be changed through the changeAdmin
function. However, if an attacker is able to manipulate or guess the current admin
address, they can call this function and verify any charity address without restriction.
The privilege escalation occurs because the contract relies on the admin
address being controlled securely, but this can be bypassed in certain cases if an attacker manages to perform a reentrancy attack on the changeAdmin
function or if they are able to directly interact with the admin address.
The vulnerability exists due to the following reasons:
Unrestricted Admin Change: The admin
can be changed via the changeAdmin
function, which only checks if the caller is the current admin
. If the contract is deployed with a weak or compromised admin, an attacker can change the admin
to their own address and take full control of the contract.
Lack of Address Validation: The function verifyCharity
does not verify that the charity being verified is legitimate beyond just checking if it's registered. This means that an attacker could potentially manipulate a charity address (which might not actually be a charity) to be verified.
Lack of Event Logging: There are no events emitted when critical functions, such as verifyCharity
, are executed. This means that there's no transparency or visibility of operations, which could make it difficult to track any unauthorized changes in the system.
This vulnerability can lead to privilege escalation in the contract, allowing an attacker to:
Verify Non-Registered Charities: If an attacker changes the admin to their own address (via exploiting changeAdmin
), they can then verify any charity they choose, even if it hasn’t been registered properly.
Gain Full Control: Since the admin can be changed, an attacker could hijack the admin role entirely and have the ability to both verify and register charities at will, essentially taking full control of the contract.
Affect the Integrity of the Charity System: This would undermine the contract’s purpose, which is to create a secure registry of verified charities. It could also lead to manipulation of the registered and verified charity list, making it useless for end-users who expect an authenticated charity list.
Foundry: Foundry was used to perform testing and to simulate attacks against the CharityRegistry
contract. Foundry’s fast testing capabilities helped us check different scenarios, including reentrancy attacks and privilege escalation exploits.
Slither: Static analysis was done using Slither to detect common vulnerabilities like reentrancy, unchecked calls, and visibility issues.
MythX: Automated vulnerability detection service used for identifying deeper vulnerabilities and logic flaws in the contract.
Etherscan: Contract verification and testing were performed on the deployed contract to simulate how it interacts with real addresses and users.
Secure Admin Functions:
Replace the admin
variable with a more secure role-based access control system. Use OpenZeppelin's Ownable
contract or a similar access control pattern to ensure only the proper users can perform critical operations.
Implement a multi-signature wallet for changing critical parameters like admin
to make sure a single attacker cannot hijack the contract.
Restrict Admin Privileges:
In the verifyCharity
function, implement additional checks to verify that the charity is valid, not just that it’s registered. This could involve checks against trusted oracle services or validators.
Add additional logic to ensure that the admin cannot be changed without meeting some criteria, such as requiring multiple approvals or a time lock.
Add Event Logging:
Emit events in critical functions, such as verifyCharity
, to provide transparency and visibility into changes. Example: Emit an event each time a charity is verified, and each time the admin is changed.
Refactor changeAdmin
Function:
Ensure that the changeAdmin
function is resistant to attack by introducing additional checks such as:
Time lock or multi-signature wallet approval.
A check to ensure that the sender has been authenticated through some other means (e.g., a recovery mechanism).
Auditing and Testing:
Perform thorough unit testing and formal verification on smart contract logic.
Use manual auditing, static code analysis tools (like Slither), and runtime monitoring on the mainnet.
changeAdmin
"The vulnerability allows an attacker to hijack the contract's admin role using the changeAdmin
function, giving them the ability to verify or register any charity.
Attacker: An entity who manipulates the contract to take over the admin role and verify non-registered charities.
Victim: A charity that could be wrongly verified by an attacker, or an external user trusting the contract’s integrity.
Protocol: The CharityRegistry
contract which maintains the list of verified charities.
Attacker deploys the contract and registers a valid charity.
Attacker hijacks the admin role by calling changeAdmin
.
After becoming the admin, they can verify any address, including unregistered addresses.
The contract’s charity registry is compromised, and the attacker can add or verify any charity they want.
The privilege escalation vulnerability in the CharityRegistry
contract exposes it to severe risks, including manipulation of the verified charity list and full control over the contract. The issue arises from inadequate access control around admin functions and the ability to change the admin address. It is recommended to refactor the contract to use stronger access control patterns, introduce transparency through event logging, and implement multi-signature or time-lock mechanisms for sensitive operations.
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.