Mystery Box

First Flight #25
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: low
Invalid

Lack of Input Validation Vulnerability on `addReward` Function

Summary

The addReward function in the MysteryBox contract was identified as vulnerable to a lack of input validation, allowing the addition of rewards with invalid or misleading values. This vulnerability could lead to scenarios where users are deceived into believing they have earned valuable rewards when, in reality, the reward value might be zero or the name could be an empty string. Tests confirmed that without proper validation, malicious or careless inputs could introduce rewards that mislead users. This report highlights the risks associated with inadequate input validation and demonstrates how to enforce proper constraints to ensure the integrity of smart contract data.

Vulnerability Details

The addReward function lacked validation checks to ensure that rewards added to the contract had meaningful values and non-empty names. As a result, it was possible to introduce rewards with a value of zero or with an empty string as the reward name, creating confusion for users.

Details:

  • Absence of Input Validation: The function did not validate that the reward's value was greater than zero or that the reward's name was non-empty.

  • Impact: Malicious actors or careless inputs could add worthless rewards or misleading entries to the reward pool, causing users to mistakenly believe they had earned valuable rewards.

Code Analysis

Original addReward Function:

function addReward(string memory _name, uint256 _value) public {
require(msg.sender == owner, "Only owner can add rewards");
rewardPool.push(Reward(_name, _value));
}

Key Issues:

  • The function allowed any string or value to be passed, including empty strings for _name or a value of 0 for _value.

Mitigated Version with Input Validation

function addReward(string memory _name, uint256 _value) public {
require(msg.sender == owner, "Only owner can add rewards");
require(_value > 0, "Reward value must be greater than zero");
require(bytes(_name).length > 0, "Reward name cannot be empty");
rewardPool.push(Reward(_name, _value));
}

Key Strength:

  • By enforcing the requirement that _value must be greater than zero and _name must not be an empty string, the function now prevents the addition of misleading or worthless rewards.

Proof of Concept (PoC)

  1. Before Mitigation: Tests were conducted to simulate the addition of invalid rewards. The function allowed adding a reward with an empty name and a reward with a value of zero, demonstrating the lack of input validation.

function testAddRewardEmptyName() public {
vm.startPrank(owner);
// Attempt to add a reward with an empty name
mysteryBox.addReward("", 1 ether);
// Fetch the rewards to verify
MysteryBox.Reward[] memory rewards = mysteryBox.getRewardPool();
// Verify that the reward with an empty name was added
assertEq(rewards[rewards.length - 1].name, "", "The reward name should be an empty string");
assertEq(rewards[rewards.length - 1].value, 1 ether, "The reward value should be 1 ether");
emit log("Test passed: The contract allows adding rewards with an empty name.");
vm.stopPrank();
}
function testAddRewardInvalidValue() public {
vm.startPrank(owner);
// Attempt to add a reward with a value of 0
mysteryBox.addReward("FakeGold", 0);
// Fetch the rewards to verify
MysteryBox.Reward[] memory rewards = mysteryBox.getRewardPool();
// Verify that the reward with a value of 0 was added
assertEq(rewards[rewards.length - 1].value, 0, "The reward should have a value of 0");
assertEq(rewards[rewards.length - 1].name, "FakeGold", "The reward name should be 'FakeGold'");
emit log("Test passed: The contract allows adding rewards with a value of 0.");
vm.stopPrank();
}

Results:

  • Before Mitigation: The tests showed that the contract accepted rewards with an empty name and a value of zero, demonstrating the lack of proper validation.

  1. After Mitigation: The tests were repeated after implementing input validation, and attempts to add rewards with invalid values resulted in reverted transactions, as expected.

Logs:
[FAIL: revert: Reward name cannot be empty] testAddRewardEmptyName() (gas: 13075)
[FAIL: revert: Reward value must be greater than zero] testAddRewardInvalidValue() (gas: 13127)

Results:

  • The mitigation successfully prevented the addition of rewards with invalid values, confirming that the input validation works as intended.

Impact

  • Prevention of Misleading Rewards: The original implementation allowed adding misleading or worthless rewards, which could have confused users or been exploited maliciously.

  • Effective Mitigation: The addition of input validation prevents such scenarios, ensuring that all rewards added to the contract are valid and meaningful.

Tools Used

  • Manual code analysis

  • Foundry for testing the input validation vulnerability

Recommendations

  1. Always Validate User Input: Implement checks for input values in all functions, especially those that modify state variables, to prevent unwanted or malicious data from being introduced.

  2. Conduct Thorough Testing: Use testing frameworks like Foundry to simulate different scenarios and ensure that input validation functions as intended.

  3. Monitor Reward Pool Integrity: Regularly audit the contents of critical data structures like rewardPool to maintain data integrity.

Conclusion

The addReward function was vulnerable due to a lack of input validation, allowing the introduction of rewards with empty names or zero values. By implementing input validation, this vulnerability was successfully mitigated, ensuring that only meaningful and valid rewards can be added to the contract. This serves as a reminder of the importance of validating all user inputs in Ethereum smart contracts to maintain data integrity and prevent exploitation.

Updates

Appeal created

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!