From e2e3a622ce40857ae51bcfbef39ce7ee3270acfa Mon Sep 17 00:00:00 2001 From: Matthew Slipper Date: Thu, 16 Jun 2022 13:02:39 -0600 Subject: [PATCH] proxyd: Use canned response for eth_accounts (#2801) We never want to expose Geth's accounts to the public internet, so proxyd will now return `[]` for `eth_accounts` RPC calls without hitting the backend. Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- proxyd/proxyd/backend.go | 12 ++++++++++++ proxyd/proxyd/integration_tests/batching_test.go | 15 +++++++++++++++ proxyd/proxyd/integration_tests/testdata/ws.toml | 3 ++- proxyd/proxyd/integration_tests/ws_test.go | 6 ++++++ proxyd/proxyd/rpc.go | 8 ++++++++ proxyd/proxyd/server.go | 8 ++++++++ 6 files changed, 51 insertions(+), 1 deletion(-) diff --git a/proxyd/proxyd/backend.go b/proxyd/proxyd/backend.go index 94e94d1..46e5225 100644 --- a/proxyd/proxyd/backend.go +++ b/proxyd/proxyd/backend.go @@ -625,6 +625,18 @@ func (w *WSProxier) clientPump(ctx context.Context, errC chan error) { continue } + // Send eth_accounts requests directly to the client + if req.Method == "eth_accounts" { + msg = mustMarshalJSON(NewRPCRes(req.ID, emptyArrayResponse)) + RecordRPCForward(ctx, BackendProxyd, "eth_accounts", RPCRequestSourceWS) + err = w.writeClientConn(msgType, msg) + if err != nil { + errC <- err + return + } + continue + } + RecordRPCForward(ctx, w.backend.Name, req.Method, RPCRequestSourceWS) log.Info( "forwarded WS message to backend", diff --git a/proxyd/proxyd/integration_tests/batching_test.go b/proxyd/proxyd/integration_tests/batching_test.go index 59c6eb5..1bcbba9 100644 --- a/proxyd/proxyd/integration_tests/batching_test.go +++ b/proxyd/proxyd/integration_tests/batching_test.go @@ -18,6 +18,8 @@ func TestBatching(t *testing.T) { netVersionResponse1 := `{"jsonrpc": "2.0", "result": "1.0", "id": 1}` callResponse1 := `{"jsonrpc": "2.0", "result": "ekans1", "id": 1}` + ethAccountsResponse2 := `{"jsonrpc": "2.0", "result": [], "id": 2}` + type mockResult struct { method string id string @@ -98,6 +100,19 @@ func TestBatching(t *testing.T) { maxBatchSize: 2, numExpectedForwards: 3, }, + { + name: "eth_accounts does not get forwarded", + mocks: []mockResult{ + callMock1, + }, + reqs: []*proxyd.RPCReq{ + NewRPCReq("1", "eth_call", nil), + NewRPCReq("2", "eth_accounts", nil), + }, + expectedRes: asArray(callResponse1, ethAccountsResponse2), + maxBatchSize: 2, + numExpectedForwards: 1, + }, } for _, tt := range tests { diff --git a/proxyd/proxyd/integration_tests/testdata/ws.toml b/proxyd/proxyd/integration_tests/testdata/ws.toml index 27ecb23..f86b22f 100644 --- a/proxyd/proxyd/integration_tests/testdata/ws.toml +++ b/proxyd/proxyd/integration_tests/testdata/ws.toml @@ -1,7 +1,8 @@ ws_backend_group = "main" ws_method_whitelist = [ - "eth_subscribe" + "eth_subscribe", + "eth_accounts" ] [server] diff --git a/proxyd/proxyd/integration_tests/ws_test.go b/proxyd/proxyd/integration_tests/ws_test.go index 563b689..6a63f71 100644 --- a/proxyd/proxyd/integration_tests/ws_test.go +++ b/proxyd/proxyd/integration_tests/ws_test.go @@ -178,6 +178,12 @@ func TestWS(t *testing.T) { "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32700,\"message\":\"parse error\"},\"id\":null}", "{\"jsonrpc\": \"2.0\", \"method\": true}", }, + { + "eth_accounts", + "{}", + "{\"jsonrpc\":\"2.0\",\"result\":[],\"id\":1}", + "{\"jsonrpc\": \"2.0\", \"method\": \"eth_accounts\", \"id\": 1}", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/proxyd/proxyd/rpc.go b/proxyd/proxyd/rpc.go index 7809132..5f16822 100644 --- a/proxyd/proxyd/rpc.go +++ b/proxyd/proxyd/rpc.go @@ -142,6 +142,14 @@ func NewRPCErrorRes(id json.RawMessage, err error) *RPCRes { } } +func NewRPCRes(id json.RawMessage, result interface{}) *RPCRes { + return &RPCRes{ + JSONRPC: JSONRPCVersion, + Result: result, + ID: id, + } +} + func IsBatch(raw []byte) bool { for _, c := range raw { // skip insignificant whitespace (http://www.ietf.org/rfc/rfc4627.txt) diff --git a/proxyd/proxyd/server.go b/proxyd/proxyd/server.go index f34da71..f0db531 100644 --- a/proxyd/proxyd/server.go +++ b/proxyd/proxyd/server.go @@ -32,6 +32,8 @@ const ( defaultMaxUpstreamBatchSize = 10 ) +var emptyArrayResponse = json.RawMessage("[]") + type Server struct { backendGroups map[string]*BackendGroup wsBackendGroup *BackendGroup @@ -248,6 +250,12 @@ func (s *Server) handleBatchRPC(ctx context.Context, reqs []json.RawMessage, isB continue } + if parsedReq.Method == "eth_accounts" { + RecordRPCForward(ctx, BackendProxyd, "eth_accounts", RPCRequestSourceHTTP) + responses[i] = NewRPCRes(parsedReq.ID, emptyArrayResponse) + continue + } + group := s.rpcMethodMappings[parsedReq.Method] if group == "" { // use unknown below to prevent DOS vector that fills up memory