Skip to content

🟡 On-chain metadata URI is write-once and completely unvalidated #1023

Description

@Ejirowebfi

Area: Smart contract · lib.rs (set_metadata) + frontend rendering

Description

set_metadata accepts any String as metadata_uri — no scheme check, no length bound beyond
Soroban's value limits, no CID shape check — and then locks it forever (MetadataAlreadySet). Two
distinct problems compound:

  1. Garbage-in, locked forever: a typo'd CID, an https:// URL to a server that later dies, or an
    outright empty/junk string becomes the token's permanent metadata pointer. There is no
    correct-after-mistake path, not even for the token creator, and no admin override — a single
    mis-click permanently disfigures a token that may carry real economic value.
  2. Untrusted sink: clients (this app, explorers, other dApps) resolve whatever the string says.
    The frontend guards ipfs:// at fetch time, but the contract-level contract ("metadata_uri is an
    IPFS URI", as the docs claim) is unenforced, so every consumer must implement its own defenses
    against javascript:, data:, oversized, or malicious URIs.

Tasks

  • Validate the URI on-chain: require the ipfs:// prefix (or the documented allow-list of
    schemes), enforce a sane maximum length (e.g. ≤ 128 bytes), and reject empty strings with a
    dedicated InvalidMetadataUri error.
  • Replace hard write-once with a governed update path: allow the token creator to update the URI
    a bounded number of times or within a grace window, or add an explicit
    freeze_metadata(token_address) the creator calls to make it immutable intentionally. Emit
    meta events on every change so history stays auditable.
  • Schema/ABI documentation updates + migration step if storage shape changes.
  • Frontend: surface the mutability state ("metadata frozen" badge), validate the CID shape
    client-side before paying the metadata fee.
  • Tests: scheme rejection, length bounds, update-then-freeze flow, unauthorized update attempts,
    event emission per change.

Acceptance criteria

  • The contract rejects any metadata URI that is not a bounded-length ipfs:// (or explicitly
    allow-listed) string, proven by tests.
  • A creator can recover from a wrong URI through the governed update path, and can deliberately
    freeze metadata; both states are visible in the UI.

Issue 19 of 20 from the codebase audit tracked in ISSUES.md.

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26auditFrom the ISSUES.md codebase auditreleasedseverity: elevatedCorrectness/robustness gap with user-visible impact

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions