57314 sc medium signature replay and hash collision via abi encodepacked in signatureverifier sol

  • Submitted on: Oct 25th 2025 at 07:13:23 UTC by @iehnnkta for Audit Comp | Belongarrow-up-right

  • Report ID: #57314

  • Report Type: Smart Contract

  • Severity: Medium

  • Target: https://github.com/immunefi-team/audit-comp-belong/blob/main/contracts/v2/platform/Factory.sol

  • Impact: Unauthorized minting of NFTs

Description / Intro

  • The factory creates Access Tokens using an off-chain signature which is verified in SignatureVerifier::checkAccessTokenInfo.

  • The signed message is constructed with abi.encodePacked over multiple dynamic fields (name, symbol, contractURI, feeNumerator, chainId).

  • This concatenation is ambiguous because abi.encodePacked concatenates raw bytes of dynamic strings without length delimiters. Distinct inputs can collide (for example, "USDC" + "USDC" == "USD" + "CUSDC" when concatenated), enabling signature collisions across different (name, symbol) pairs.

Vulnerability Details

  • SignatureVerifier::checkAccessTokenInfo hashes:

    • keccak256(abi.encodePacked(name, symbol, contractURI, feeNumerator, block.chainid))

  • Because abi.encodePacked does not include length separators for dynamic types, different combinations of inputs can produce the same byte sequence and thus the same hash and signature.

  • Example collision: a signature issued for (name = "USDC", symbol = "USDC") can be reused to create a different collection with (name = "USD", symbol = "CUSDC").

Impact

  • Authorization bypass for collection creation: an attacker can deploy unauthorized collections using a signature intended for a different collection.

  • Collection spoofing and loss of control over what the platform signs; potential reputational damage and misdirected user funds.

  • The same issue appears across the SignatureVerifier contract wherever abi.encodePacked is used for hashing signed data.

References

  • https://github.com/immunefi-team/audit-comp-belong/blob/a17f775dcc4c125704ce85d4e18b744daece65af/contracts/v2/utils/SignatureVerifier.sol#L53-L74

  • https://github.com/immunefi-team/audit-comp-belong/blob/a17f775dcc4c125704ce85d4e18b744daece65af/contracts/v2/utils/SignatureVerifier.sol#L81-L99

Mitigation

  • Replace abi.encodePacked with abi.encode when building the message to hash. abi.encode includes type and length information, preventing ambiguous concatenation.

  • Alternatively, use EIP-712 typed structured data signing to robustly encode signed fields.

Proof of Concept

Use the following test inside factory.test.ts under the Deployment describe block.

1

Setup & context

  • The test demonstrates a signature collision where a signature for (name = "USDC", symbol = "USDC") is reused to create a different collection (name = "USD", symbol = "CUSDC").

  • Fixture provides: factory, alice, bob, signer, and chainId.

2

1) Alice obtains a valid signature and creates (name = "USDC", symbol = "USDC")

Code:

3

2) Bob reuses the same signature to create (name = "USD", symbol = "CUSDC")

Code (continuation):

Test output after running:

This confirms a successful reuse of the same signature to create two distinct collections due to encoding ambiguity.

Was this helpful?