Description
In the createMemorabiliaCollection() function, the baseUri string provided by the organizer is not validated beyond checking that it's non-empty:
```javascript
require(bytes(baseUri).length > 0, "URI required");
```
However, there's no check to validate whether the URI is:
- A well-formed URI (e.g., starts with ipfs:
- Free from potentially malicious or misleading schemes
- Duplicate (to prevent URI spoofing across collections)
Risk
Impact:
Improper or malicious baseUri inputs can result in:
1. NFTs pointing to broken or off-chain metadata
2. Abuse by fake collections using someone else's URI
3. User confusion in marketplaces or UI integrations
4. Reputation damage if scammy or invalid URLs are used
Proof of Concept
```javascript
festivalPass.createMemorabiliaCollection(
"ScamDrop",
"not-a-real-uri",
1e18,
100,
true
);
This creates a collection where all metadata links like:
`not-a-real-uri/metadata/1` are non-functional or misleading — possibly exploited in marketplaces to impersonate valid collections.
=> Real-World Example
- A malicious organizer could use the URI of an existing reputable project (e.g., another festival or NFT line)
and trick users into thinking it's official.
- This also creates issues for marketplaces like OpenSea that depend on consistent metadata formats.
Recommended Mitigation
```diff
function createMemorabiliaCollection(
string memory name,
string memory baseUri,
uint256 priceInBeat,
uint256 maxSupply,
bool activateNow
) external onlyOrganizer returns (uint256) {
require(priceInBeat > 0, "Price must be greater than 0");
require(maxSupply > 0, "Supply must be at least 1");
require(bytes(name).length > 0, "Name required");
require(bytes(baseUri).length > 0, "URI required");
+ require(bytes(baseUri).length > 5, "Invalid URI format");
+ require(keccak256(bytes(baseUri)) != keccak256(bytes("")), "Empty URI hash");
// rest of function
```