DatingDapp

First Flight #33
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: low
Invalid

JSON Injection in SoulboundProfileNFT Metadata

Summary

The tokenURI function in the SoulboundProfileNFT contract constructs JSON metadata using unsanitized user-provided inputs (name and profileImage). Attackers can inject malicious characters (e.g., ", \, <>) to break the JSON structure, corrupt metadata, or execute cross-site scripting (XSS) attacks in applications that parse the metadata.


Vulnerability Details

Location

  • Contract: SoulboundProfileNFT.sol

  • Function: tokenURI

Root Cause

  1. Unsanitized Inputs:

    • The name and profileImage fields (set by users during profile creation) are directly inserted into the JSON string without escaping special characters.

    • Example: A name containing " or \ will break the JSON syntax.

  2. Missing Validation:

    • No checks are performed to ensure name and profileImage conform to safe standards (e.g., alphanumeric characters only).

Code Snippet (Vulnerable Code)

function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
// ... existing checks ...
string memory profileName = _profiles[tokenId].name;
string memory imageURI = _profiles[tokenId].profileImage;
return string(
abi.encodePacked(
'{"name":"', profileName, '", ',
'"description":"A soulbound dating profile NFT.", ',
'"attributes": [{"trait_type": "Age", "value": ', Strings.toString(profileAge), "}], ",
'"image":"', imageURI, '"}'
)
);
}

Impact

Severity: Medium

  • Metadata Corruption: Malicious users can create profiles with invalid JSON, causing applications (e.g., marketplaces, wallets) to fail when rendering the NFT.

  • XSS Risk: If the metadata is displayed in a web context without sanitization, attackers could inject scripts via profileImage URLs.

  • Reputation Damage: The protocol may be seen as insecure, especially if third-party integrations break due to invalid metadata.


Proof of Concept (PoC)

Example Attack

  1. Malicious Profile Creation:

    // User submits a name with JSON-breaking characters
    nft.mintProfile("Alice\"}, \"hacked\": true, {\"name\": \"Evil", 25, "ipfs://legit-image");
  2. Resulting Corrupted JSON:

    {
    "name": "Alice"}, "hacked": true, {"name": "Evil",
    "description": "A soulbound dating profile NFT.",
    "attributes": [...],
    "image": "ipfs://legit-image"
    }

    This invalid JSON breaks parsers and injects a fake hacked field.


Recommended Mitigation

Input Validation

Restrict name and profileImage to safe characters during minting:

function mintProfile(string memory name, uint8 age, string memory profileImage) external {
// Validate name (alphanumeric + spaces)
bytes memory nameBytes = bytes(name);
for (uint256 i = 0; i < nameBytes.length; i++) {
require(
nameBytes[i] == ' ' ||
(nameBytes[i] >= '0' && nameBytes[i] <= '9') ||
(nameBytes[i] >= 'A' && nameBytes[i] <= 'Z') ||
(nameBytes[i] >= 'a' && nameBytes[i] <= 'z'),
"Invalid name"
);
}
// Validate profileImage (e.g., allow only URLs starting with http/https/ipfs)
require(bytes(profileImage).length > 0, "Invalid image URL");
// ... rest of the code ...
}

n.

Updates

Appeal created

n0kto Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

invalid_URI_injection_scam_underaged_bad_name_photo_etc

Scamming/phishing is not the protocol problem, that's a user mistake. NFT are unique, even if someone does a copy of your profile (which is also possible in web2), I consider it informational. Injection is a problem for the web2 part of the protocol, not a bug here. For the age, it depends on the countries law and future medicine. Anyways, that's more an ethical/political problem, not a bug.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.