DatingDapp

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

`abi.encodePacked()` Can Cause Hash Collisions in SoulboundProfileNFT

abi.encodePacked() Can Cause Hash Collisions

Description:

The contract uses abi.encodePacked() inside the tokenURI function when constructing the JSON metadata. While this is not directly used for hashing, using abi.encodePacked() with multiple dynamic arguments can lead to ambiguous encoding issues if ever used in hashing or comparisons in future contract updates.

Impact:

  • Hash collisions: If abi.encodePacked() is used with multiple dynamic parameters and then hashed (e.g., with keccak256()), different inputs can lead to the same hash.

  • Potential misinterpretation: While this doesn't directly introduce a security issue in tokenURI, it's best practice to use abi.encode() instead when working with multiple dynamic types.

Proof of Concept (Example of Hash Collision):

keccak256(abi.encodePacked(uint256(0x123), uint256(0x456))) == keccak256(abi.encodePacked(uint256(0x1), uint256(0x23456)))

This results in the same bytes output due to lack of padding, which can be exploited in scenarios involving hashed data verification.

Affected Code:

return string(
abi.encodePacked( // 🔴 Potential issue
_baseURI(),
Base64.encode(
bytes(
abi.encodePacked(
'{"name":"',
profileName,
'", ',
'"description":"A soulbound dating profile NFT.", ',
'"attributes": [{"trait_type": "Age", "value": ',
Strings.toString(profileAge),
"}], ",
'"image":"',
imageURI,
'"}'
)
)
)
)
);

Recommended Mitigation:

Since abi.encodePacked() is used only for string concatenation here, a safer approach is to use bytes.concat() instead of abi.encodePacked().

Fixed Code:
return string(
bytes.concat( // ✅ Safer alternative
bytes(_baseURI()),
Base64.encode(
bytes.concat(
bytes('{"name":"'),
bytes(profileName),
bytes('", "description":"A soulbound dating profile NFT.", '),
bytes('"attributes": [{"trait_type": "Age", "value": '),
bytes(Strings.toString(profileAge)),
bytes("}], "),
bytes('"image":"'),
bytes(imageURI),
bytes('"}')
)
)
)
);

Why This Fix Works:

  • bytes.concat() explicitly handles dynamic types safely, reducing the risk of unexpected encoding issues.

  • It preserves clarity by handling individual strings as bytes, avoiding encoding inconsistencies.

Updates

Appeal created

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

Informational or Gas

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

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