Skip to content
Last updated: December 19, 2024

SCWE-019: Insecure Signature Verification

Content in BETA

This content is in beta and still under active development, so it is subject to change any time (e.g. structure, IDs, content, URLs, etc.).

Send Feedback

Relationships

Description

Insecure signature verification occurs when a contract improperly verifies a cryptographic signature or fails to securely validate signatures, allowing attackers to forge or manipulate them. This vulnerability can allow unauthorized transactions or the bypassing of important security mechanisms, potentially leading to fraud, unauthorized access, or other attacks.

Common causes of insecure signature verification include: - Not validating the signer's address. - Using weak or outdated cryptographic libraries. - Failing to check signature validity before processing actions. - Incorrectly handling the signature format.

Remediation

  • Verify signatures properly: Always verify that the signature matches the intended signer by using the ecrecover function for Ethereum addresses and comparing the result to the expected signer address.
  • Use strong cryptographic methods: Ensure the use of robust cryptographic techniques and libraries. Avoid using outdated or weak algorithms.
  • Use secure signature formats: Make sure that signature formats are validated properly (e.g., ensure proper handling of v, r, s values in Ethereum signatures).
  • Implement checks before acting on the signature: Always perform checks for valid signature and relevant parameters before executing any logic that could be influenced by the signature.

Samples

Insecure Signature Verification

pragma solidity ^0.8.0;

contract InsecureSignatureExample {
    address public owner;

    constructor() public {
        owner = msg.sender;
    }

    // Insecure signature verification: does not properly validate the signature
    function executeTransaction(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public {
        address signer = ecrecover(hash, v, r, s);  // Signature verification
        if (signer == owner) {
            // Execute some sensitive action
        }
    }
}
In the insecure version, the contract checks if the signature corresponds to the owner but does not properly validate or handle potential issues with the signature, such as its format or correctness.

Fixed Signature Verification

pragma solidity ^0.8.0;

contract SecureSignatureExample {
    address public owner;

    constructor() public {
        owner = msg.sender;
    }

    // Secure signature verification: properly checks signature and signer
    function executeTransaction(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public {
        address signer = ecrecover(hash, v, r, s);
        require(signer == owner, "Invalid signature");  // Ensure valid signature before proceeding
        // Execute some sensitive action
    }
}
In the fixed version, we use the require() function to ensure the signature matches the owner's address, thereby improving security by preventing unauthorized access or actions.