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>
This commit is contained in:
parent
e7191f335c
commit
e2e3a622ce
@ -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",
|
||||
|
@ -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 {
|
||||
|
@ -1,7 +1,8 @@
|
||||
ws_backend_group = "main"
|
||||
|
||||
ws_method_whitelist = [
|
||||
"eth_subscribe"
|
||||
"eth_subscribe",
|
||||
"eth_accounts"
|
||||
]
|
||||
|
||||
[server]
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user