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

setPassword() input data is publicly accessible, therefore allowing anyone to retrieve the password

Summary

When calling the setPassword() function, the function argument is publicly accessible using the input data from the transaction, therefore allowing anyone to retrieve the stored password.

Vulnerability Details

The protocol's goal is to allow only s_owner to call getPassword() and retrieve the stored password in s_password. However, when calling the setPassword() function, the function argument is publicly accessible using the input data from the transaction, therefore allowing anyone to retrieve the password used in any transaction that called the setPassword() function. By retrieving the password from the last transaction that called the setPassword() function, anyone can retrieve the stored password.

@> function setPassword(string memory newPassword) external {
s_password = newPassword;
emit SetNetPassword();
}

Impact

Anyone can retrieve the password used in the last transaction that called the setPassword() function, therefore rendering the entire protocol's goal useless.

The following Foundry commands show how to retrieve the password from a transaction that called the setPassword() function:

// 1) start a local anvil node
make anvil
// 2) deploy contract (in a new terminal)
make deploy
// 3) set a new password using the contract address from 2)
cast send `contract address` "setPassword(string memory)" "myNewPassword" --rpc-url http://localhost:8545 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
// 4) cast tx using the transaction hash from 3)
cast tx `tx hash`
// 5) cast the last 32 bytes (64 hex-digits) from the input data to ascii
cast to-ascii 6d794e657750617373776f726400000000000000000000000000000000000000
// myNewPassword

Tools Used

  • Foundry

Recommendations

Don't use this protocol at all, since it's generally a bad idea to store private data on EVM compatible blockchains.

If you insist on using this protocol, you can encrypt the password off-chain before calling the setPassword() function. However, in this case you need to store the encryption key off-chain, which renders the protocol redundant as you could use the encryption key or part of it as your password.

Updates

Lead Judging Commences

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

finding-anyone-can-read-storage

Private functions and state variables are only visible for the contract they are defined in and not in derived contracts. In this case private doesn't mean secret/confidential

Support

FAQs

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