Skip to content

[HIGH] Reentrancy allows arbitrary contracts to impersonate the signer during meta-calls #254

@cygent-dev

Description

@cygent-dev

Security Finding

Field Value
Severity HIGH
Category reentrancy
Repository 1inch/solidity-utils
Confidence 56%

Description

This issue is a reentrancy-based privilege escalation. BySig::bySig() stores the signer before executing arbitrary delegatecall payloads, then removes it afterward:

function bySig(address signer, SignedCall calldata sig, bytes calldata signature) public payable returns(bytes memory ret) {
    ...
    _msgSenders.push(signer);
    ret = address(this).functionDelegateCall(sig.data);
    _msgSenders.pop();
}

[Truncated - see PR for full details]

Location

  • BySig.sol:L120-L129 in bySig (BySig)
  • BySig.sol:L195-L201 in _msgSender (BySig)

Impact

Any inheriting contract automatically exposes all _msgSender()-gated functionality (fund transfers, governance, configuration) to arbitrary external contracts that can trigger reentrancy while a meta-transaction is running, enabling theft or total control without additional signatures.

Recommendation

Track the relayer for each stack frame and only honor the stored signer when the current msg.sender still matches that relayer; fall back to the real sender otherwise. Alternatively, add a dedicated non-reentrancy guard so external calls cannot reenter while the signer context is active.

[Truncated - see PR for full details]


Created by CARA Security Audit via Cygent

Metadata

Metadata

Assignees

No one assigned

    Labels

    cygent:highHigh severity security findingcygent:openSecurity finding - Open

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions