Private Data Exposure Remediation
Overview
Related Detector: Private Data Exposure
Solidity’s private and internal control contract-to-contract access, not confidentiality. Every storage slot is readable by anyone via eth_getStorageAt, and every transaction input is public. Storing a password, secret key, or hidden parameter in a private variable exposes it. The remediation is to never place a secret on-chain in the clear — keep it off-chain and commit only to a binding hash.
Recommended Fix
Before (Vulnerable)
contract Game {
bytes32 private secret; // fully readable via eth_getStorageAt
function setSecret(bytes32 s) external onlyOwner { secret = s; }
}
After (Fixed — commit-reveal, no plaintext secret on-chain)
contract Game {
bytes32 public commitment; // hash only; the preimage stays off-chain
function commit(bytes32 c) external onlyOwner { commitment = c; }
function reveal(bytes32 secret, bytes32 salt) external {
require(keccak256(abi.encodePacked(secret, salt)) == commitment, "Bad reveal");
// act on the now-public secret
}
}
Store only a keccak256(secret, salt) commitment; reveal later when the value is meant to become public. For data that must stay confidential indefinitely, keep it entirely off-chain.
Common Mistakes
- Believing
privatehides a value from users; it only blocks other contracts from reading it directly. - Committing to
keccak256(secret)without a salt, allowing a brute-force/rainbow-table recovery of low-entropy secrets. - Passing the secret as a plaintext transaction argument during “reveal” before it should be public — the mempool sees it.