Arbitrary Storage Write
id: LS03C
title: Arbitrary Storage Write
baseSeverity: C
category: storage-corruption
language: solidity
blockchain: [ethereum]
impact: Overwrite critical contract variables (e.g., owner, balances, logic pointers)
status: draft
complexity: high
attack_vector: external
mitigation_difficulty: hard
versions: [">=0.4.0", "<0.8.21"]
cwe: CWE-123
swc: SWC-124
π Description
- Arbitrary Storage Write occurs when a smart contract allows a user to write to any storage slot, either due to:
- Misused low-level operations like
assemblyordelegatecall, - Lack of bounds checking in
sstore-like patterns - Improper deserialization of calldata or storage pointers.
- This enables attackers to overwrite sensitive variables such as
owner,balances, orimplementationaddresses in proxies, often leading to total contract compromise.
π¨ Vulnerable Code
contract UnsafeStorage {
function writeToSlot(uint256 slot, bytes32 value) external {
assembly {
sstore(slot, value) // β unguarded arbitrary write
}
}
}
π§ͺ Exploit Scenario
Step-by-step exploit process:
- Attacker calls writeToSlot() with slot = 0 and their address as value.
- This overwrites slot 0, which typically stores owner or implementation.
- Attacker now has control over the contract and can drain funds, upgrade logic, or selfdestruct.
Assumptions:
- Storage slot layout is predictable or known.
- Function allows external control over storage index without access control or bounds checks.
β Fixed Code
contract SafeStorage {
address public owner;
modifier onlyOwner() {
require(msg.sender == owner, "Not authorized");
_;
}
function updateOwner(bytes32 newOwner) external onlyOwner {
assembly {
sstore(0, newOwner) // β
Only called by authorized user
}
}
}
π§ Contextual Severity
- context: "Default"
severity: C
reasoning: "Attacker can rewrite admin, logic, or balancesβcomplete takeover or corruption."
- context: "Upgradeable proxy system with no access control"
severity: C
reasoning: "System can be hijacked or bricked instantly."
- context: "Properly scoped internal admin-only call"
severity: L
reasoning: "Still dangerous, but controlled internally with limits."
π‘οΈ Prevention
Primary Defenses
- Never expose raw sstore/sload or slot-based writes to user input.
- Avoid assembly-based writes unless absolutely necessary and protected.
- Use standard high-level Solidity constructs (mapping, structs, Ownable).
Additional Safeguards
- If using proxies, ensure implementation slots follow EIP-1967 or hardened storage patterns.
- Use access control (onlyOwner, onlyProxyAdmin) rigorously.
- Validate and sanitize any index or offset used to write to storage.
Detection Methods
- Slither: low-level-write, arbitrary-sstore, dangerous-assembly detectors.
- Manual code audit for sstore, delegatecall, or storage[] usage.
- Formal analysis or fuzzing with randomized slot access and input injection.
π°οΈ Historical Exploits
- Name: Multichain Storage Collision
- Date: 2023
- Loss: ~$1.9M
- Post-mortem: Link to post-mortem
π Further Reading
- SWC-124: Arbitrary Storage Write
- Solidity Docs β Storage Layout
- OpenZeppelin β Proxy Storage Slots
- EIP-1967 β Standard Proxy Storage Slots
β Vulnerability Report
id: LS03C
title: Arbitrary Storage Write
severity: C
score:
impact: 5
exploitability: 4
reachability: 4
complexity: 3
detectability: 4
finalScore: 4.4
π Justifications & Analysis
- Impact: Overwrites critical storage slots (e.g., owner, implementation, balances).
- Exploitability: A single crafted slot and value combo can hijack the contract.
- Reachability: Often exposed via developer backdoors or debug features.
- Complexity: Medium β attacker must understand the storage slot layout.
- Detectability: Highly detectable in audits with proper Slither rules or grep-based search.