From 69c298ef20e524ca7f43456ae031a8a929c0befb Mon Sep 17 00:00:00 2001 From: rakesh0x7 <19131a05p3@gvpce.ac.in> Date: Sat, 1 Jun 2024 23:18:55 +0530 Subject: [PATCH 1/2] update private data on-chain --- .../unencrypted-private-data-on-chain.md | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/vulnerabilities/unencrypted-private-data-on-chain.md b/vulnerabilities/unencrypted-private-data-on-chain.md index a4179e7..c44c148 100644 --- a/vulnerabilities/unencrypted-private-data-on-chain.md +++ b/vulnerabilities/unencrypted-private-data-on-chain.md @@ -1,3 +1,51 @@ ## Unencrypted Private Data On-Chain -Ethereum smart contract code, storage, and any data transacted on-chain can always be read. Treat it as such. Even if your code is not verified on Etherscan, attackers can still decompile or check transactions to and from it to analyze it. For this reason, it's imperative that private data is never stored on-chain unencrypted. \ No newline at end of file +Ethereum smart contract code, storage, and any data transacted on-chain can always be read. Treat it as such. Even if your code is not verified on Etherscan, attackers can still decompile or check transactions to and from it to analyze it. For this reason, it's imperative that private data is never stored on-chain unencrypted. + +### Explanation + +When data is stored on-chain, it is accessible to anyone who can read the blockchain. This includes all transaction data and contract storage. Even if the source code of your smart contract is not publicly verified, an attacker can decompile the bytecode to analyze its functionality and access storage data. + +### Example + +Let's consider a scenario where a user stores their email, password, and username on-chain without encryption: + +```solidity +// Vulnerable contract storing unencrypted private data +pragma solidity ^0.8.0; + +contract UserInfo { + struct User { + string username; + string email; + string password; + } + + mapping(address => User) private users; + + function setUserInfo(string memory _username, string memory _email, string memory _password) public { + users[msg.sender] = User(_username, _email, _password); + } + + function getUserInfo() public view returns (string memory, string memory) { + User memory user = users[msg.sender]; + return (user.username, user.email); + } +} +``` + +In this contract, the `users` mapping stores the username, email, and password in plain text. Although the `users` mapping is marked as private, this only means it is not accessible via other smart contracts. However, anyone can read the blockchain and view the stored values. + +### Protection Mechanisms +To protect sensitive data, consider the following strategies: + +1) Encryption: Encrypt data before storing it on-chain. Only store encrypted data and manage decryption keys off-chain. +2) Off-Chain Storage: Store sensitive data off-chain and only reference it on-chain when necessary. +3) Zero-Knowledge Proofs: Use cryptographic techniques such as zero-knowledge proofs to validate data without revealing it. + +### References + +- [Medium Article: Attack Vectors in Solidity #4: Unencrypted Private Data On-Chain](https://medium.com/@natachigram/attack-vectors-in-solidity-4-unencrypted-private-data-on-chain-cf4f3ff1cf71) +- [Solidity by Example: Accessing Private Data](https://solidity-by-example.org/hacks/accessing-private-data/) +- [SWC Registry: Unencrypted Private Data On-Chain](https://swcregistry.io/docs/SWC-136) +- [Zero-Knowledge Proofs](https://blog.ethereum.org/2016/12/05/zksnarks-in-a-nutshell/) \ No newline at end of file From f157e7055ad7a29fcf876cf5d28ec02e2807ab77 Mon Sep 17 00:00:00 2001 From: rakesh0x7 <19131a05p3@gvpce.ac.in> Date: Tue, 4 Jun 2024 16:59:55 +0530 Subject: [PATCH 2/2] update example --- .../unencrypted-private-data-on-chain.md | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/vulnerabilities/unencrypted-private-data-on-chain.md b/vulnerabilities/unencrypted-private-data-on-chain.md index c44c148..b7a8673 100644 --- a/vulnerabilities/unencrypted-private-data-on-chain.md +++ b/vulnerabilities/unencrypted-private-data-on-chain.md @@ -2,46 +2,44 @@ Ethereum smart contract code, storage, and any data transacted on-chain can always be read. Treat it as such. Even if your code is not verified on Etherscan, attackers can still decompile or check transactions to and from it to analyze it. For this reason, it's imperative that private data is never stored on-chain unencrypted. -### Explanation - -When data is stored on-chain, it is accessible to anyone who can read the blockchain. This includes all transaction data and contract storage. Even if the source code of your smart contract is not publicly verified, an attacker can decompile the bytecode to analyze its functionality and access storage data. - ### Example -Let's consider a scenario where a user stores their email, password, and username on-chain without encryption: +Let's consider a scenario where players participate in an Odd or Even game. Each player submits a number, and the winner is determined by the sum of both numbers being odd or even. Here is a vulnerable implementation: ```solidity // Vulnerable contract storing unencrypted private data -pragma solidity ^0.8.0; - -contract UserInfo { - struct User { - string username; - string email; - string password; +contract OddEven { + struct Player { + address payable addr; + uint number; } - - mapping(address => User) private users; - - function setUserInfo(string memory _username, string memory _email, string memory _password) public { - users[msg.sender] = User(_username, _email, _password); + + Player[2] private players; + uint8 count = 0; + + function play(uint number) public payable { + require(msg.value == 1 ether); + players[count] = Player(payable(msg.sender), number); + count++; + if (count == 2) selectWinner(); } - - function getUserInfo() public view returns (string memory, string memory) { - User memory user = users[msg.sender]; - return (user.username, user.email); + + function selectWinner() private { + uint n = players[0].number + players[1].number; + players[n % 2].addr.transfer(address(this).balance); + delete players; + count = 0; } } ``` -In this contract, the `users` mapping stores the username, email, and password in plain text. Although the `users` mapping is marked as private, this only means it is not accessible via other smart contracts. However, anyone can read the blockchain and view the stored values. +In this contract, the `players` array stores the submitted numbers in plain text. Although the `players` array is marked as private, this only means it is not accessible via other smart contracts. However, anyone can read the blockchain and view the stored values. This means the first player's number will be visible, allowing the second player to select a number that they know will make them a winner. ### Protection Mechanisms To protect sensitive data, consider the following strategies: -1) Encryption: Encrypt data before storing it on-chain. Only store encrypted data and manage decryption keys off-chain. -2) Off-Chain Storage: Store sensitive data off-chain and only reference it on-chain when necessary. -3) Zero-Knowledge Proofs: Use cryptographic techniques such as zero-knowledge proofs to validate data without revealing it. +1) Commit-Reveal Scheme: Use a commit-reveal scheme where the data is committed to the blockchain in one phase and revealed in another. +2) Zero-Knowledge Proofs: Use cryptographic techniques such as zero-knowledge proofs to validate data without revealing it. ### References