Skip to content

eth_sign and eth_signTypedData bypass AllowInsecureUnlock JSON-RPC gate #4607

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions