Smart Contract / Uninitialized Storage Pointer
Description
Uninitialized Storage Pointer (USP) is a type of smart contract vulnerability classified within the Common Weakness Enumeration (CWE) directory as CWE-845. It is a type of insecure coding practice that occurs when a program fails to check if a storage pointer has been initialized to a valid memory address or not. In the context of smart contracts, USP refers to a security vulnerability that arises when a function is called with a storage pointer that is not initialized or has been set to a default value, such as 0 or an empty address. The Security Weakness Classification (SWC) directory categorizes this vulnerability as SWC-117.
Risk
The risk associated with uninitialized storage pointer (USP) is that it can lead to data corruption and loss. If a storage pointer is not initialized or set properly, the data stored at the memory address associated with the pointer may be corrupted or even completely wiped. In the context of smart contracts, this can lead to errors in the contract logic or even result in the loss of funds held in the contract.
Solution
The best way to prevent USP vulnerabilities is to ensure that all storage pointers are initialized and set to valid memory addresses before they can be used. This can be done by using a code review process to check for any uninitialized storage pointers, as well as by using a static analysis tool such as the OWASP Testing Guide to detect any uninitialized storage pointers. Additionally, a secure coding process should be used to ensure that storage pointers are initialized and set properly before they are used.
Example
The following code example is taken from a Common Vulnerabilities and Exposures (CVE) report. It shows a function that fails to check if a storage pointer has been initialized or not before using it:
function transfer(address _to, uint256 _value) public {
uint256 tokenBalance;
tokenBalance = balances[msg.sender]; // Uninitialized Storage Pointer
require(tokenBalance >= _value);
balances[msg.sender] = tokenBalance - _value;
balances[_to] = balances[_to] + _value;
Transfer(msg.sender, _to, _value);
}
Here, the function fails to check if the storage pointer for the tokenBalance
variable is initialized and set to a valid memory address before using it. This could lead to data corruption and loss if the storage pointer is not properly initialized.