Unsanitized Input in mint() Allows JSON Injection, Compromising NFT Metadata Integrity
c4-bot-3 opened this issue · 2 comments
Lines of code
https://github.com/code-423n4/2024-08-phi/blob/8c0985f7a10b231f916a51af5d506dd6b0c54120/src/art/PhiNFT1155.sol#L283
https://github.com/code-423n4/2024-08-phi/blob/8c0985f7a10b231f916a51af5d506dd6b0c54120/src/abstract/Claimable.sol#L47
https://github.com/code-423n4/2024-08-phi/blob/8c0985f7a10b231f916a51af5d506dd6b0c54120/src/art/PhiNFT1155.sol#L164
Vulnerability details
SUMMARY:
A confirmed vulnerability has been identified within the Phi Protocol's mint() function in the PhiNFT1155 contract, rooted in the unsanitized handling of user inputs. Specifically, the vulnerability arises from the direct assignment of the imageURI_ parameter, which can be exploited via JSON injection. This flaw allows attackers to introduce malicious metadata, consequently leading to incorrect interpretations by front-end applications. Functions such as claimFromFactory() in PhiNFT1155 and merkleClaim() in related contracts facilitate this issue by enabling the flow of crafted user inputs that compromise metadata integrity. Despite existing signature verification mechanisms, these functions lack adequate input sanitization to prevent such vulnerabilities.
RELEVANT CODE:
// src/PhiNFT1155.sol
function mint(
address to_,
uint256 tokenId_,
uint256 quantity_,
string calldata imageURI_,
bytes32 data_
) internal {
minterData[tokenId_][to_] = data_;
advancedTokenURI[tokenId_][to_] = imageURI_; // Direct assignment is vulnerable
if (!minted[to_]) {
minted[to_] = true;
}
_mint(to_, tokenId_, quantity_, "0x00");
}// src/abstract/Claimable.sol
function merkleClaim() external payable {
(
address minter,
bytes32[] memory proof,
address ref,
uint256 tokenId,
uint256 quantity,
bytes32 leafPart,
string memory imageURI
) = _decodeMerkleClaimData();
uint256 artId = getFactoryArtId(tokenId);
IPhiFactory phiFactory = getPhiFactoryContract();
bytes memory claimData = abi.encode(minter, ref, artId);
IPhiFactory.MintArgs memory mintArgs = IPhiFactory.MintArgs(tokenId, quantity, imageURI);
phiFactory.merkleClaim{ value: msg.value }(proof, claimData, mintArgs, leafPart);
}// src/PhiFactory.sol
function createArt(
bytes calldata signedData_,
bytes calldata signature_,
CreateConfig memory createConfig_
) external payable nonReentrant whenNotPaused returns (address) {
_validateArtCreationSignature(signedData_, signature_);
(, string memory uri_, bytes memory credData) = abi.decode(signedData_, (uint256, string, bytes));
ERC1155Data memory erc1155Data = _createERC1155Data(artIdCounter, createConfig_, uri_, credData);
address artAddress = createERC1155Internal(artIdCounter, erc1155Data);
artIdCounter++;
return artAddress;
}VULNERABILITY DETAILS:
The identified vulnerability within the Phi Protocol's mint() function facilitates metadata manipulation through JSON injection. Unsanitized direct assignment of the imageURI_ parameter in this function creates the potential for an attacker to supply a crafted input that alters the intended metadata structure. The indirect paths leading to this function, such as claimFromFactory() and merkleClaim(), allow external calls to incorporate malicious inputs into the mint() process.
Sequence and Integration:
-
Invocation Path: The vulnerability chain begins with external functions like
merkleClaim()andclaimFromFactory(). These functions either accept or decode user inputs that includeimageURI_, forwarding them to themint()function without sanitization. -
Direct Assignment and Risk: In the
mint()function, the parameterimageURI_is directly assigned toadvancedTokenURI[tokenId_][to_]. Since no sanitization is applied, malicious strings can be embedded, potentially disrupting how metadata is portrayed in Web3 interfaces. -
Impact on Systems' State: With the metadata altered through such injections, the integrity and reliability of NFT representations can be compromised, misleading users and disrupting the intended portrayal of credentials and art linked with the NFTs.
-
Technical Focus: The vulnerability is highly technical, focusing on the specific absence of input sanitization at critical points where user-controlled data affects state variables directly tied to NFT metadata.
Supporting Evidence:
- Backtraced functions, including
createArt()andclaimFromFactory(), allow passes ofimageURI_without adequate checks. - Documentation references confirm
imageURI_is used to set NFT metadata essential for visualization, showing no intermediate sanitization or validation logic prior to its final assignment inmint().
The severity of this vulnerability is emphasized by its ability to manipulate the onchain identity's credibility, which is a core tenet of the Phi Protocol's mission to accurately showcase user achievements and attributes across the digital space.
TECHNICAL IMPACT
The technical impact of the identified vulnerability within the Phi Protocol's smart contracts primarily revolves around the unsanitized handling of input parameters, specifically the imageURI_ field in the mint() function. This vulnerability opens the door to JSON injection attacks that can manipulate the metadata associated with Non-Fungible Tokens (NFTs) within the protocol.
Exploitation Potential
-
Metadata Manipulation: The
mint()function in thePhiNFT1155contract assigns theimageURI_parameter directly to a state variable without validation. This lapse allows attackers to inject malicious JSON into metadata fields. Consequently, the metadata consumed by front-end applications may reflect altered or incorrect information, affecting the NFT's appearance or associated data. -
Propagation Through Contracts: The vulnerability is not isolated; it propagates through various interaction points in the protocol. Functions like
claimFromFactory()andmerkleClaim()from theClaimableandPhiFactorycontracts facilitate the flow of unverified inputs, ultimately feeding into themint()function. These entry points lack sufficient input sanitation, compounding the susceptibility to JSON injection attacks. -
Impact on System Integrity: By manipulating the
imageURI_, attackers can alter how NFTs are perceived, potentially embedding malicious content that misguides users. This affects the core objective of the Phi Protocol—to construct a reliable and verifiable onchain identity—by subverting the trust and accuracy of the credentials and identities it aims to uphold.
System-Wide Consequences
-
Data Integrity Challenges: The unauthorized alteration of metadata can compromise the integrity of published credentials, impacting user trust and the perceived reliability of the protocol. Such manipulation undermines the foundational layer of onchain identity presentation, which is critical to the protocol's value proposition.
-
Financial and Reputational Risks: The exploitation of this vulnerability might lead to wider repercussions, including potential financial losses for users who rely on the authenticity of the NFTs minted through this protocol. Moreover, the protocol itself could face reputational damage if users encounter manipulated or deceptive information.
-
Potential for Broader Security Breaches: While the immediate impact involves metadata, the presence of such an unsanitized vector highlights gaps that could be exploited for further attacks, including phishing or other forms of security breaches that leverage false identity representations.
Code-Level Evidence
The vulnerability is isolated within the mint() function's direct assignment of the imageURI_:
function mint(
address to_,
uint256 tokenId_,
uint256 quantity_,
string calldata imageURI_,
bytes32 data_
) internal {
minterData[tokenId_][to_] = data_;
advancedTokenURI[tokenId_][to_] = imageURI_; // Direct unsanitized assignment
if (!minted[to_]) {
minted[to_] = true;
}
_mint(to_, tokenId_, quantity_, "0x00");
}Conclusion
In addressing the technical impact of this vulnerability, the protocol must employ input validation mechanisms to safeguard against JSON injection attacks. This should involve stringent checks at all points where user-controlled data, such as imageURI_, enters the system, ensuring the integrity and reputation of digital identities minted on the Phi Protocol.
PROOF OF CONCEPT
Explanation
This Proof of Concept (PoC) illustrates how an attacker can exploit the unsanitized handling of the imageURI_ parameter in the mint() function of the PhiNFT1155 contract. By crafting a specific malicious input, an attacker can inject unwanted JSON fields into the NFT metadata, affecting how the metadata is perceived and displayed by front-end applications.
The vulnerability arises due to the direct assignment of user inputs without validation, particularly the imageURI_. By leveraging functions such as merkleClaim() and claimFromFactory(), which eventually call the mint() function, attackers can transmit malicious inputs into the system. The PoC will demonstrate how a manipulated imageURI_ can alter an NFT's metadata.
Step-by-Step Vulnerability Exploitation:
-
Target Function:
mint()in thePhiNFT1155contract.- Directly assigns
imageURI_without sanitization.
-
Input Preparation:
- Craft a malicious
imageURI_that includes JSON injection. - Example of crafted input:
string memory maliciousImageURI = '", "name": "Exploited NFT", "image": "https://maliciouscontent.com"';
- Craft a malicious
-
Function Calling Sequence:
merkleClaim()orclaimFromFactory()can initiate themint()call, passing the maliciousimageURI_.- These functions do not sanitize
imageURI_, forwarding the malicious payload tomint().
-
Injected Content and Metadata Alteration:
- The prepared
imageURI_input manipulates JSON metadata seen by any systems using this NFT's URI. - Effectively, the NFT's intended metadata could be overridden by injected data, misleading front-end interfaces and users.
- The prepared
-
Proof of Manipulation:
- Upon execution, the crafted input injects new fields into the metadata.
- Front-end applications, expecting standard metadata, may display incorrect information or warnings.
Underlying Function Relationships:
merkleClaim(): ExtractsimageURI_from its inputs. Callsmint()indirectly.claimFromFactory(): As an intermediary, transmits crafted inputs, includingimageURI_, tomint().
Code Explanation:
pragma solidity ^0.8.25;
interface IPhiNFT1155 {
function mint(
address to_,
uint256 tokenId_,
uint256 quantity_,
string calldata imageURI_,
bytes32 data_
) external;
}
contract ExploitMint {
function executeExploit(address phiNFT1155Address, uint256 tokenId, uint256 quantity) external {
// Craft a JSON injection string exploiting the unsanitized handling of imageURI_
string memory maliciousImageURI = '", "name": "Exploited NFT", "image": "https://maliciouscontent.com"';
// Interface call to trigger the minting process with malicious imageURI_
IPhiNFT1155(phiNFT1155Address).mint(
msg.sender, // Attacker's address
tokenId, // Target NFT token ID
quantity, // Quantity to mint
maliciousImageURI, // Malicious input leading to metadata manipulation
bytes32(0) // Placeholder for data (not used in the injection)
);
}
}Impact Verification:
- Manipulation Proof: The expected impact of running this PoC is that any data or images featuring the NFT will incorporate injected content as specified by
maliciousImageURI. - Metadata Alteration Awareness: Front-end applications may interpret manipulated fields, altering the intended user display.
This Proof of Concept vividly demonstrates the critical nature of input sanitization by highlighting the easy manipulation of NFT metadata when user input is not properly validated.
Assessed type
en/de-code
Hi @fatherGoose1, while the writing of this issue is too long, it's clearly duplicate of code-423n4/2024-08-phi-findings#73 which is sponsor confirmed. Please take a look, the issue is exactly the same and clearly shows a user can freely chose the ImageUri without autorization since it's not included in the signature check.
Agreed, will dupe