Skip to content

eth_sign and eth_signTypedData bypass AllowInsecureUnlock JSON-RPC gate #4607

@kingpinXD

Description

@kingpinXD

Summary

eth_sign and eth_signTypedData in the JSON-RPC backend skip the AllowInsecureUnlock check that the other four account-related RPCs enforce. When an operator runs with --json-rpc.allow-insecure-unlock=false expecting account-related signing over HTTP to be blocked, these two endpoints still produce signatures from the loaded keyring.

Vulnerable code (on main HEAD 9a516a34d)

  • rpc/backend/sign_tx.go:124-142Backend.Sign() accesses b.ClientCtx.Keyring.SignByAddress with no AllowInsecureUnlock guard.
  • rpc/backend/sign_tx.go:147-168Backend.SignTypedData() same pattern, no guard.

For comparison, the correctly guarded endpoints all open with if !b.Cfg.JSONRPC.AllowInsecureUnlock { return ..., fmt.Errorf("account unlock with HTTP access is forbidden") }:

  • rpc/backend/sign_tx.go:22-27SendTransaction()
  • rpc/backend/node_info.go:34Accounts()
  • rpc/backend/node_info.go:84SetEtherbase()
  • rpc/backend/node_info.go:225ListAccounts()

Fix

A fix already exists on the remote branch origin/worktree-fix-eth-sign-insecure-unlock (commit d8ea64168, dated 2026-03-24) that adds the four-line guard to both functions. Merge that branch (or land an equivalent two-function patch) plus unit tests asserting the error response when the flag is false. Also worth adding a sweep test or linter check that asserts every Backend method touching b.ClientCtx.Keyring.Sign* either has the AllowInsecureUnlock guard or an explicit comment justifying why it does not, so the next account-related RPC we add does not repeat the omission.

Severity / impact

Classified as Low on HackenProof. eth_sign returns a \x19Ethereum Signed Message-prefixed signature only useful for off-chain auth flows; eth_signTypedData can produce EIP-712 signatures usable for ERC-2612 permit-drain or off-chain marketplace orders, but the realistic fund-extraction path requires four operator-side preconditions to converge (flag set to false against the default true, funded EVM key loaded into validator keyring against standard operator practice, EIP-712-eligible assets controlled by that key, and a publicly reachable RPC port). The realistic population on ZetaChain mainnet satisfying all four is plausibly zero. The fix ships as code hygiene rather than incident response.

Source

HackenProof report: https://dashboard.hackenproof.com/manager/companies/zetachain/zetachain-blockchain-software/reports/ZCNode-284

Metadata

Metadata

Assignees

No one assigned

    Labels

    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