DatingDapp

AI First Flight #6
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Missing Input Validation Allows Invalid Profile Data

Root + Impact

Description

  • Describe the normal behavior in one or more sentences


  • Explain the specific issue or problem in one or more sentences

  • Data quality and platform integrity issues

function mintProfile(string memory name, uint8 age, string memory profileImage) external {
require(profileToToken[msg.sender] == 0, "Profile already exists");
// ❌ No validation on inputs:
// - name can be empty ""
// - age can be 0 or 255
// - profileImage can be empty or invalid
// - Strings can be extremely long
uint256 tokenId = ++_nextTokenId;
_safeMint(msg.sender, tokenId);
_profiles[tokenId] = Profile(name, age, profileImage);
}// Root cause in the codebase with @> marks to highlight the relevant section

Risk

Likelihood:

  • Reason 1 // Describe WHEN this will occur (avoid using "if" statements)

  • Reason 2

Impact:

  • Impact 1

  • Poor data quality

  • Spam/fake profiles

  • Gas griefing with extremely long strings

  • Impact 2

Proof of Concept

// All of these succeed but shouldn't:
// Empty profile
vm.prank(alice);
nft.mintProfile("", 0, "");
// Child account (potential legal issues)
vm.prank(bob);
nft.mintProfile("Bob", 12, "ipfs://bob");
// Unrealistic age
vm.prank(carol);
nft.mintProfile("Carol", 255, "ipfs://carol");
// Extremely long name (gas griefing)
string memory longName = new string(10000); // 10KB name
vm.prank(dave);
nft.mintProfile(longName, 25, "ipfs://dave");

Recommended Mitigation

- remove this code
+ add this code
uint8 public constant MIN_AGE = 18; // For dating app compliance
uint8 public constant MAX_AGE = 120;
uint256 public constant MAX_NAME_LENGTH = 50;
uint256 public constant MAX_IMAGE_LENGTH = 200;
function mintProfile(
string memory name,
uint8 age,
string memory profileImage
) external {
require(profileToToken[msg.sender] == 0, "Profile already exists");
// Validate name
require(bytes(name).length > 0, "Name cannot be empty");
require(bytes(name).length <= MAX_NAME_LENGTH, "Name too long");
// Validate age (critical for dating apps!)
require(age >= MIN_AGE, "Must be 18 or older");
require(age <= MAX_AGE, "Invalid age");
// Validate image URL
require(bytes(profileImage).length > 0, "Image URL cannot be empty");
require(bytes(profileImage).length <= MAX_IMAGE_LENGTH, "Image URL too long");
// Optional: Validate image URL format
require(
_startsWith(profileImage, "ipfs://") ||
_startsWith(profileImage, "https://"),
"Invalid image URL format"
);
uint256 tokenId = ++_nextTokenId;
_safeMint(msg.sender, tokenId);
_profiles[tokenId] = Profile(name, age, profileImage);
profileToToken[msg.sender] = tokenId;
emit ProfileMinted(msg.sender, tokenId, name, age, profileImage);
}
function _startsWith(string memory str, string memory prefix)
private
pure
returns (bool)
{
bytes memory strBytes = bytes(str);
bytes memory prefixBytes = bytes(prefix);
if (strBytes.length < prefixBytes.length) {
return false;
}
for (uint i = 0; i < prefixBytes.length; i++) {
if (strBytes[i] != prefixBytes[i]) {
return false;
}
}
return true;
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 2 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!