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

Every password that is set using 'setPassword' is public to everyone

Summary

Due to the nature of the EVM, every person is able to find out what the variable s_password is, even though it's marked as private.

Vulnerability Details

In Solidity, private means that the variable is only accessible in the contract where it has been defined. This means, if Contract B would inherit from PasswordStore.sol, they would not be able to access s_password and s_owner since they are both declared as private variables:

address private s_owner;
string private s_password;

However, due to the nature of the EVM, the fact that private variables are only accessible in the contract they are declared in, does not mean that it can not be viewed by anyone.

Storage in the EVM is constructed of slots of with a length of 2**256, each slot can hold up to 32 bytes.
The EVM stores the variables in the order that they have been declared. If multiple variables are able to fit in one slot, they will be packed together to safe space.

In our case, the first variable declared is s_owner which has the type address, address is 20 bytes. This will go in slot 0. Our second variable, s_password is of type string. A string works a bit different.

If the string is less that 32 bytes long, it is all written in the length storage slot with byte 0 encoding the string length * 2 and all other 31 bytes used to store the string data.

If the string is more than 32 bytes long : the length storage slot holds only the value of string length * 2 + 1, and storage slot(s) starting at keccak256(length_slot) hold the data.

So, it depends on the length of the string. Let's consider the following scenario:

  • Alice uses setPassword to set her password to: "myPassword"

  • Bob is going to try to retrieve the password

How is he going to do it?

For example, if the contract was deployed to mainnet, Bob could fork the mainnet using Foundry and use the following command to get the storage in slot 1:
cast storage $CONTRACT_ADDRESS 1

This would return the hex value, decode this and you would get the password!

Impact

Tools Used

Manual Review

Recommendations

NEVER store sensitive information on the blockchain.

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.