NFT Metadata Tampering
id: LS22H
title: NFT Metadata Tampering
baseSeverity: H
category: metadata-integrity
language: solidity
blockchain: [ethereum]
impact: NFT holders or marketplaces may be deceived by altered or manipulated metadata
status: draft
complexity: medium
attack_vector: internal
mitigation_difficulty: medium
versions: [">=0.6.0", "<latest"]
cwe: CWE-345
swc: SWC-131
π Description
- NFT metadata tampering occurs when the token URI (
tokenURI) or metadata contents of an NFT can be changed after minting, allowing the project owner or a malicious actor to: - Switch traits or visuals, modifying rarity after reveal,
- Inject harmful or fraudulent content,
- Mislead collectors or marketplaces about the true identity or utility of the token.
- This breaks the core principle of immutability and trustlessness, particularly in projects that use centralized servers or lack URI locking mechanisms.
π¨ Vulnerable Code
contract MutableNFT is ERC721 {
mapping(uint256 => string) private _tokenURIs;
function setTokenURI(uint256 tokenId, string memory uri) external onlyOwner {
_tokenURIs[tokenId] = uri; // β Mutable after mint
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
return _tokenURIs[tokenId];
}
}
π§ͺ Exploit Scenario
Step-by-step manipulation:
- Project deploys an NFT collection where tokenURI can be changed post-mint.
- A buyer purchases a rare NFT with a valuable trait (e.g., βgold backgroundβ).
- After the sale, the project owner modifies the URI, removing the rare trait or replacing it with a common one.
- The holder now owns a different NFT than what was advertised.
Assumptions:
- An attacker gains admin access to a metadata server and changes JSON files without on-chain auditability.
- Marketplaces and collectors rely on incorrect metadata during sale or valuation.
β Fixed Code
contract ImmutableNFT is ERC721 {
mapping(uint256 => string) private _tokenURIs;
bool public metadataFrozen;
function setTokenURI(uint256 tokenId, string memory uri) external onlyOwner {
require(!metadataFrozen, "Metadata frozen");
_tokenURIs[tokenId] = uri;
}
function freezeMetadata() external onlyOwner {
metadataFrozen = true; // β
Locks all metadata forever
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
return _tokenURIs[tokenId];
}
}
π§ Contextual Severity
- context: "Public NFT project with mutable metadata after mint"
severity: H
reasoning: "Severe user deception and financial harm possible"
- context: "Private or artistic project with disclosed mutability"
severity: M
reasoning: "Impact depends on transparency and buyer expectations"
- context: "NFT metadata and images fully content-addressed and immutable"
severity: I
reasoning: "Vulnerability mitigated by design"
π‘οΈ Prevention
Primary Defenses
- Lock metadata permanently using freezeMetadata() or by removing setters post-reveal.
- Host metadata on decentralized, immutable storage like IPFS or Arweave.
- Emit events when metadata is revealed or frozen (MetadataFrozen()).
Additional Safeguards
- Make tokenURI deterministic and based on token ID (e.g., baseURI + id).
- Use access controls and audit trails for any metadata editing tools.
- Store content hashes on-chain to verify external metadata integrity.
Detection Methods
- Slither: mutable-uri, post-mint-uri-change, admin-controlled-uri detectors.
- Manual audits for any setTokenURI, updateURI, or mutable metadata patterns.
- Check for dynamic tokenURI() logic relying on off-chain variables.
π°οΈ Historical Exploits
- Name: Bored Ape Yacht Club Metadata Tampering Incident
- Date: 2021
- Loss: Potential reputational damage and user trust erosion
- Post-mortem: Link to post-mortem
π Further Reading
- SWC-131: Incorrect Calculation or Relying on External Values
- OpenZeppelin ERC721 Metadata Guidelines
- Best Practices for NFT Metadata
β Vulnerability Report
id: LS22H
title: NFT Metadata Tampering
severity: H
score:
impact: 4
exploitability: 3
reachability: 4
complexity: 2
detectability: 5
finalScore: 3.85
π Justifications & Analysis
- Impact: High β alters perceived value and breaks trust in NFT immutability.
- Exploitability: Medium β requires access, but often retained by project owners.
- Reachability: Widespread in early-stage or lazy-mint projects.
- Complexity: Low β one mutable mapping or setter function is all it takes.
- Detectability: High β clear in audit and tooling scans.