This was an internal Web3 solidity security training in XREX. I want to share these materials with everyone interested in Web3 security and how to find vulnerabilities in code and exploit them. Every vulnerability testing uses Foundry. Faster and easier!
A collection of vulnerable code snippets taken from Solidity by Example, SWC Registry and Blockchain CTF, etc.
- Follow the instructions to install Foundry.
- Clone and run command:
git submodule update --init --recursive ## initialize submodule dependencies
- Test vulnerability:
forge test --contracts ./src/test/Reentrancy.sol -vvvv
- Integer Overflow 1 | Integer Overflow 2 :
- In previous versions of Solidity (prior Solidity 0.8.x) an integer would automatically roll-over to a lower or higher number.
- Without SafeMath (prior Solidity 0.8.x)
- Selfdestruct 1 | Selfdestruct 2 :
- Due to missing or insufficient access controls, malicious parties can self-destruct the contract.
- The selfdestruct(address) function removes all bytecode from the contract address and sends all ether stored to the specified address.
- Unsafe Delegatecall :
- This allows a smart contract to dynamically load code from a different address at runtime.
- Reentrancy :
- One of the major dangers of calling external contracts is that they can take over the control flow.
- Not following checks-effects-interactions pattern and no ReentrancyGuard.
- ERC777 callbacks and reentrancy :
- Unsafe low level call - call injection :
- Use of low level "call" should be avoided whenever possible. It can lead to unexpected behavior if return value is not handled properly.
- Private data :
- Private data ≠ Secure. It's readable from slots of the contract.
- it's important that unencrypted private data is not stored in the contract code or state.
- Unprotected callback - NFT over mint :
- _safeMint is secure? Attacker can reenter the mint function inside the onERC721Received callback.
- Backdoor assembly :
- Malicious attacker can inject inline assembly to manipulate conditions. Change implementation contract or sensitive parameters.
- Bypass iscontract :
- During contract creation when the constructor is executed there is no code yet so the code size will be 0.
- DOS :
- External calls can fail accidentally or deliberately, which can cause a DoS condition in the contract. (DoS with unexpected revert)
- Randomness :
- Use of global variables like block hash, block number, block timestamp and other fields is insecure, miner and attacker can control it.
- Visibility :
- Insecure visibility settings give attackers straightforward ways to access a contract's private values or logic.
- Real case : FlippazOne NFT | 88mph NFT | CoinstoreNFT Public Burn | Sandbox LAND Public Burn
- txorigin - phishing :
- tx.origin is a global variable in Solidity which returns the address of the account that sent the transaction. Using the variable for authorization could make a contract vulnerable if an authorized account calls into a malicious contract.
- Uninitialized state variables :
- Uninitialized local storage variables may contain the value of other storage variables in the contract; this fact can cause unintentional vulnerabilities, or be exploited deliberately.
- Storage collision 1 | Storage collision 2 (Audius) :
- If variable’s storage location is fixed and it happens that there is another variable that has the same index/offset of the storage location in the implementation contract, then there will be a storage collision. REF
- Approval scam :
- Too many scams abusing approve or setApprovalForAll to drain your tokens.
- Signature replay 1 | Signature replay 2 (NBA):
- Data location - storage vs memory :