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

Exposing `PasswordStore::s_password` as an on-chain string allows unauthorized access

Summary

Declaring PasswordStore::s_password() as private does not guarantee that it cannot be accessed on-chain. Attackers can inspect contract transactions to retrieve values stored in the contract's state.

Vulnerability Details

Any user can make an RPC call to access this slot in the contract and retrieve the stored value.

- string private s_password;

Proof of Concept (PoC)

The script and commands below demonstrates the validity and severity of the vulnerability.

How to Run the PoC

Requirements

  • Install Foundry.

  • Clone the project codebase to your local workspace.

  • Create a .env file in your root folder and add the required variables.

  • The .env file should follow this format:

RPC_URL=
PRIVATE_KEY=
ETHERSCAN_API_KEY=

Step-by-step Guide to Run the PoC

  1. Ensure the above requirements are met.

  2. Load .env variables into the terminal by running source .env.

  3. Deploy the contracts by executing the following command in your terminal:

forge script script/DeployPasswordStore.s.sol:DeployPasswordStore --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast -vv
  1. Copy the contract address into a notepad.

  2. Note that s_password is set as "myPassword" in the deploy script.

  3. Read the s_password value from the contract storage by running:

cast storage 0xPasswordStoreContractAddress 1 --rpc-url $RPC_URL
  • Note:

    • Replace 0xPasswordStoreContractAddress with the corresponding PasswordStore contract address.

    • The return value is in byte32 format.

  1. Copy the returned data value to your notes.

  2. Finally, read the data by converting it from byte32 to ASCII using the following command:

cast --to-ascii 0xReturnedByte32Data
  • Note:

    • Replace 0xReturnedByte32Data with the corresponding byte data from your previous execution.

The return value should be "myPassword", which proves that s_password can be read from storage.

Impact

Implications

Exposing user passwords can compromise network security, as attackers can easily gain unauthorized access to user accounts. This poses a significant threat to user experience and general security.

Exploit Scenario

John sets a password for his account, believing that the protocol guarantees the security of his information. However, Sarah, a more technically inclined user, reads the value of John's password, effectively gaining access to his account.

Tools Used

  • Foundry

Recommendations

Private data should not be stored unencrypted in contract code or state. Instead, consider encrypting it or storing it off-chain to enhance security and protect user information.

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-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.

Give us feedback!