57905 sc medium signature malleability and replay attack vulnerabilities in signature verification

Submitted on Oct 29th 2025 at 12:22:31 UTC by @Sparrow_23 for Audit Comp | Belongarrow-up-right

  • Report ID: #57905

  • Report Type: Smart Contract

  • Report severity: Medium

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

  • Impacts:

    • Contract fails to deliver promised returns, but doesn't lose value

    • Unauthorized minting of NFTs

Description

Brief/Intro

The SignatureVerifier library uses a vulnerable signature scheme susceptible to signature malleability and replay attacks. The current implementation lacks essential security measures including EIP-712 compliance, nonces, deadlines, and proper s-value validation, allowing attackers to reuse or manipulate signatures indefinitely across different chains and contexts.

Vulnerability Details

ECDSA signatures are inherently malleable — given a valid signature (r, s, v), an attacker can create (r, -s mod n, v') which is also valid. The SignatureVerifier contract uses the SignatureCheckerLib library to verify signatures:

library SignatureVerifier {
    using SignatureCheckerLib for address;

But SignatureCheckerLib does not protect against malleable signatures.

The library itself contains a warning comment:

circle-exclamation

The signatures also lack a proper EIP-712 domain separator making signatures vulnerable to being replayed across chains and contracts. They are also missing nonce and deadline fields and as such cannot be cancelled and remain valid forever once generated.

All signature verification functions in the library use the vulnerable pattern:

Impact Details

This allows attackers to create alternative valid signatures for the same message by modifying the signature components leading to replay attacks and signature malleability exploitation (e.g., unauthorized minting).

References

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

  • https://github.com/immunefi-team/audit-comp-belong/blob/a17f775dcc4c125704ce85d4e18b744daece65af/node_modules/solady/src/utils/SignatureCheckerLib.sol#L19-L23

  • https://eips.ethereum.org/EIPS/eip-712

Proof of Concept

The following tests demonstrate:

  • missing nonce and deadline (signatures remain valid indefinitely)

  • missing nonce allowing replay of identical signed requests

Add the following test to factory.test.ts:

chevron-rightNotes / Contexthashtag
  • The PoC demonstrates that signatures generated today remain accepted after long time periods (no deadline) and that identical signed payloads can be reused (no nonce / used-signature tracking).

  • The existing code uses abi.encodePacked(..., block.chainid) in the message hash; adding block.chainid helps bind to a chain but does not solve malleability nor replace proper EIP-712 domain usage, nonces, deadlines, or s-value validation.

Was this helpful?