57838 sc insight missing produce name sanitization allows breaking snip 12 standard compliance

Submitted on Oct 29th 2025 at 06:35:55 UTC by @Another for Audit Comp | Belongarrow-up-right

  • Report ID: #57838

  • Report Type: Smart Contract

  • Report severity: Insight

  • Target: https://github.com/immunefi-team/audit-comp-belong/blob/feat/cairo/src/nftfactory/nftfactory.cairohttps://github.com/immunefi-team/audit-comp-belong/blob/feat/cairo/src/nftfactory/nftfactory.cairo

Description

Brief/Intro

The NFTFactory contract does not properly sanitize user-provided NFT names and symbols, allowing malicious or malformed input that can break SNIP-12 compliance. This can lead to interoperability issues with wallets, explorers, and other StarkNet infrastructure that expect properly formatted token identifiers.

Vulnerability Details

The _produce function allows the user to provide the name and symbol for the NFT. The function only checks that names and symbols are non-empty but does not validate allowed characters. This enables creation of NFTs with names and symbols that are not SNIP-12 compliant.

Relevant snippet:

nftfactory.cairo (excerpt)
        fn _produce(
            ref self: ContractState, instance_info: InstanceInfo,
        ) -> (ContractAddress, ContractAddress) {
            let info = instance_info.clone();

            assert(info.name.len().is_non_zero(), super::Errors::EMPTY_NAME);
            assert(info.symbol.len().is_non_zero(), super::Errors::EMPTY_SYMBOL);

            let metadata_name_hash: felt252 = info.name.hash();
            let metadata_symbol_hash: felt252 = info.symbol.hash();
            let contract_uri_hash: felt252 = info.contract_uri.hash();

            assert(
                self
                    .nft_info
                    .entry((metadata_name_hash, metadata_symbol_hash))
                    .nft_address
                    .read()
                    .is_zero(),
                super::Errors::NFT_EXISTS,
            );

            let message = ProduceHash {
                name_hash: metadata_name_hash,
                symbol_hash: metadata_symbol_hash,
                contract_uri: contract_uri_hash,
                royalty_fraction: info.royalty_fraction,
            };

            let hash = message.get_message_hash(get_contract_address());
            let is_valid_signature_felt = ISRC6Dispatcher {
                contract_address: self.factory_parameters.signer.read(),
            }

(unchanged links and file paths preserved)

According to SNIP-12 (StarkNet Improvement Proposal 12), token identifiers should follow additional constraints beyond non-empty strings, for example:

  • No empty name (already enforced)

  • Name can't be enclosed in parentheses

  • Name can't contain the comma (,) character (since it is used as a delimiter in the enum type)

  • ...and other character/formatting restrictions defined by SNIP-12

Impact Details

A malicious user can create NFTs with names/symbols containing special or delimiter characters that break SNIP-12 assumptions. Consequences include:

  • Interoperability issues with wallets, explorers, and other tooling expecting SNIP-12 compliant identifiers

  • Display or parsing issues in frontends, potentially enabling UI/UX issues or spoofing/confusion

circle-exclamation

References

  • https://github.com/immunefi-team/audit-comp-belong/blob/a17f775dcc4c125704ce85d4e18b744daece65af/src/nftfactory/nftfactory.cairo#L251-L285

  • https://github.com/starknet-io/SNIPs/blob/906b19074038005dc26d3574b6853a7c68d14e02/SNIPS/snip-12.md#type-identification

Proof of Concept

chevron-rightTest demonstrating creation of NFT with special characters (add to test_nftfactory.cairo)hashtag

Was this helpful?