Skip to content
Last updated: February 06, 2026

SCWE-147: Permit or Meta-Transaction Signatures Without Expiration

Stable Version v1.0

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

Send Feedback

Relationships

Description

Permit (EIP-2612) and meta-transaction signatures that omit a deadline or expiry parameter can be replayed indefinitely once obtained. An attacker who captures a valid signature (e.g., via phishing or a compromised frontend) can submit it at any future time. SCWE-105 covers domain separator and nonce; this weakness specifically addresses the absence of expiration.

Remediation

  • Include a deadline (or expiry) in the signed message and enforce require(block.timestamp <= deadline, "Expired") when processing the signature.
  • Use EIP-712 structured data with a deadline field.

Examples

Vulnerable

pragma solidity ^0.8.0;

contract MetaTx {
    function execute(address signer, bytes32 hash, uint8 v, bytes32 r, bytes32 s) external {
        require(ecrecover(hash, v, r, s) == signer, "Bad sig");
        // No deadline: signature valid forever
        _execute(signer);
    }
}

Fixed

function execute(address signer, uint256 deadline, bytes32 hash, uint8 v, bytes32 r, bytes32 s) external {
    require(block.timestamp <= deadline, "Expired");
    require(ecrecover(hash, v, r, s) == signer, "Bad sig");
    _execute(signer);
}
Note: The hash must be computed from EIP-712 structured data that includes the deadline field so the signature cannot be replayed after expiry.