Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

`PasswordStore::setPassword()` lacks access control, enabling unauthorized password changes

Summary

The absence of access control in the PasswordStore::setPassword() function allows anyone to access and modify the password.

Vulnerability Details

When a msg.sender who is not the PasswordStore::s_owner attempts to change the password, the function currently permits it. To rectify this, we should restrict access to only the owner.

function setPassword(string memory newPassword) external {
+ if(msg.sender != s_owner) revert("Caller not owner
!");
s_password = newPassword;
emit SetNetPassword();
}

Proof of Concept

The test suite below illustrates the vulnerability's validity and severity.

How to Run the Test

Requirements

  • Install Foundry.

  • Clone the project codebase into your local workspace.

  • Add the tests from the Codebase section below to the PasswordStore.t.sol file in the test folder, placing it after line 33.

Step-by-step Guide to Run the Test

  1. Ensure the above requirements are met.

  2. Execute the following command in your terminal to run the test:

forge test --match-test "test_anyone_can_set_password"

Note: Refer to the test function comments to understand the cases being tested.

Codebase

The codebase below utilizes Foundry for testing.

Test Cases

contract MorePasswordStoreTest is Test {
PasswordStore public passwordStore;
DeployPasswordStore public deployer;
address public owner;
address public notOwner;
function setUp() public {
deployer = new DeployPasswordStore();
passwordStore = deployer.run();
owner = msg.sender;
notOwner = address(1);
string memory expectedPassword = "originalPassword";
passwordStore.setPassword(expectedPassword);
}
/** @notice This test checks if other users who are not owner can set a new password. */
function test_anyone_can_set_password() public {
// Start Prank passes calls to another user -- notOwner
// notOwner changes the password
vm.startPrank(notOwner);
string memory changedPassword = "newPassword";
passwordStore.setPassword(changedPassword);
// Control is passed back to owner to be able to call getPassword
vm.startPrank(owner);
string memory currentPassword = passwordStore.getPassword();
// This assert tests that the password was changed
// and that the current password is changedPassword
assertEq(currentPassword, changedPassword);
}
}

Impact

Implications

Passing the above tests implies that the vulnerability:

  • Allows anyone to negatively affect the UX of the protocol.

  • Compromises the protocol's integrity.

  • Exposes users to potential application crashes.

Exploit Scenario

John sets a password as the account owner, but Sarah changes the password. As a result, John receives different values when attempting to retrieve the password, potentially leading to application crashes.

Tools Used

  • Foundry

Recommendations

To fix this bug, add a require statement that only allows the owner to successfully call the setPassword() function.

function setPassword(string memory newPassword) external {
+ require(msg.sender == s_owner, "Caller not owner!"); // Add this line
s_password = newPassword;
emit SetNetPassword();
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 2 years ago
inallhonesty Lead Judge about 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-lacking-access-control

Anyone can call `setPassword` and set a new password contrary to the intended purpose.

Support

FAQs

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