From d8ea64168a0db21321a5c8e42db6ade6fc6c5ac7 Mon Sep 17 00:00:00 2001 From: Charlie <31941002+CharlieMc0@users.noreply.github.com> Date: Tue, 24 Mar 2026 13:56:44 -0700 Subject: [PATCH 1/4] fix: add AllowInsecureUnlock guard to eth_sign and eth_signTypedData Sign() and SignTypedData() bypass the AllowInsecureUnlock config flag, allowing JSON-RPC callers to use the node as a signing oracle even when the operator explicitly disables insecure unlock. Add the same guard already present in SendTransaction() to both methods. Co-Authored-By: Claude Opus 4.6 (1M context) --- rpc/backend/sign_tx.go | 10 ++++++++++ rpc/backend/sign_tx_test.go | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/rpc/backend/sign_tx.go b/rpc/backend/sign_tx.go index cec9fbf1b5..93a40c7f54 100644 --- a/rpc/backend/sign_tx.go +++ b/rpc/backend/sign_tx.go @@ -122,6 +122,11 @@ func (b *Backend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, e // Sign signs the provided data using the private key of address via Geth's signature standard. func (b *Backend) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { + if !b.Cfg.JSONRPC.AllowInsecureUnlock { + b.Logger.Debug("account unlock with HTTP access is forbidden") + return nil, fmt.Errorf("account unlock with HTTP access is forbidden") + } + from := sdk.AccAddress(address.Bytes()) _, err := b.ClientCtx.Keyring.KeyByAddress(from) @@ -143,6 +148,11 @@ func (b *Backend) Sign(address common.Address, data hexutil.Bytes) (hexutil.Byte // SignTypedData signs EIP-712 conformant typed data func (b *Backend) SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) { + if !b.Cfg.JSONRPC.AllowInsecureUnlock { + b.Logger.Debug("account unlock with HTTP access is forbidden") + return nil, fmt.Errorf("account unlock with HTTP access is forbidden") + } + from := sdk.AccAddress(address.Bytes()) _, err := b.ClientCtx.Keyring.KeyByAddress(from) diff --git a/rpc/backend/sign_tx_test.go b/rpc/backend/sign_tx_test.go index c90df697ce..f94cd18c49 100644 --- a/rpc/backend/sign_tx_test.go +++ b/rpc/backend/sign_tx_test.go @@ -153,6 +153,15 @@ func (s *TestSuite) TestSign() { inputBz hexutil.Bytes expPass bool }{ + { + "fail - insecure unlock not allowed", + func() { + s.backend.Cfg.JSONRPC.AllowInsecureUnlock = false + }, + from, + nil, + false, + }, { "fail - can't find key in Keyring", func() {}, @@ -204,6 +213,15 @@ func (s *TestSuite) TestSignTypedData() { inputTypedData apitypes.TypedData expPass bool }{ + { + "fail - insecure unlock not allowed", + func() { + s.backend.Cfg.JSONRPC.AllowInsecureUnlock = false + }, + from, + apitypes.TypedData{}, + false, + }, { "fail - can't find key in Keyring", func() {}, From dd894ebf983f73227ec59e446029659cda28899d Mon Sep 17 00:00:00 2001 From: Charlie McCowan <31941002+CharlieMc0@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:21:22 -0700 Subject: [PATCH 2/4] Update rpc/backend/sign_tx.go Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- rpc/backend/sign_tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/backend/sign_tx.go b/rpc/backend/sign_tx.go index 93a40c7f54..e7b1b3aad9 100644 --- a/rpc/backend/sign_tx.go +++ b/rpc/backend/sign_tx.go @@ -150,7 +150,7 @@ func (b *Backend) Sign(address common.Address, data hexutil.Bytes) (hexutil.Byte func (b *Backend) SignTypedData(address common.Address, typedData apitypes.TypedData) (hexutil.Bytes, error) { if !b.Cfg.JSONRPC.AllowInsecureUnlock { b.Logger.Debug("account unlock with HTTP access is forbidden") - return nil, fmt.Errorf("account unlock with HTTP access is forbidden") + return nil, errors.New("account unlock with HTTP access is forbidden") } from := sdk.AccAddress(address.Bytes()) From 67176cdd9b3f6bc1ba2ef997f0240bc1e5d81f51 Mon Sep 17 00:00:00 2001 From: Charlie McCowan <31941002+CharlieMc0@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:21:37 -0700 Subject: [PATCH 3/4] Update rpc/backend/sign_tx.go Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- rpc/backend/sign_tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/backend/sign_tx.go b/rpc/backend/sign_tx.go index e7b1b3aad9..ea9d5effd1 100644 --- a/rpc/backend/sign_tx.go +++ b/rpc/backend/sign_tx.go @@ -124,7 +124,7 @@ func (b *Backend) SendTransaction(args evmtypes.TransactionArgs) (common.Hash, e func (b *Backend) Sign(address common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { if !b.Cfg.JSONRPC.AllowInsecureUnlock { b.Logger.Debug("account unlock with HTTP access is forbidden") - return nil, fmt.Errorf("account unlock with HTTP access is forbidden") + return nil, errors.New("account unlock with HTTP access is forbidden") } from := sdk.AccAddress(address.Bytes()) From 9ec9fcc7b636c20cd37edcf021084b87abbd9b9d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 25 Mar 2026 19:31:59 +0000 Subject: [PATCH 4/4] docs: add changelog entry for eth_sign AllowInsecureUnlock guard Co-authored-by: Charlie McCowan --- changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/changelog.md b/changelog.md index 445560fdb4..8aa29358d7 100644 --- a/changelog.md +++ b/changelog.md @@ -23,6 +23,7 @@ The `zetacored` binary must be upgraded to trigger chain parameters data migrati ### Fixes +* [4562](https://github.com/zeta-chain/node/pull/4562) - add AllowInsecureUnlock guard to eth_sign and eth_signTypedData * [4403](https://github.com/zeta-chain/node/pull/4403) - load Sui inbound cursors from database for all supported packages * [4401](https://github.com/zeta-chain/node/pull/4401) - retry Sui inbound when the inbound vote RPC failed * [4414](https://github.com/zeta-chain/node/pull/4414) - fix example package deployment by removing gateway object reference