From 4952d19a6c7a5700620bbecf926d9ac868e69d53 Mon Sep 17 00:00:00 2001 From: yzang2019 Date: Thu, 7 Mar 2024 16:21:31 +0800 Subject: [PATCH 1/3] Add method deny list in geth http server --- rpc/server.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/rpc/server.go b/rpc/server.go index 2742adf07b..b34cefc677 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -18,6 +18,7 @@ package rpc import ( "context" + "fmt" "io" "sync" "sync/atomic" @@ -48,6 +49,7 @@ type Server struct { mutex sync.Mutex codecs map[ServerCodec]struct{} + denyList map[string]struct{} run atomic.Bool batchItemLimit int batchResponseLimit int @@ -56,8 +58,9 @@ type Server struct { // NewServer creates a new server instance with no registered handlers. func NewServer() *Server { server := &Server{ - idgen: randomIDGenerator(), - codecs: make(map[ServerCodec]struct{}), + idgen: randomIDGenerator(), + codecs: make(map[ServerCodec]struct{}), + denyList: make(map[string]struct{}), } server.run.Store(true) // Register the default service providing meta information about the RPC service such @@ -86,6 +89,12 @@ func (s *Server) RegisterName(name string, receiver interface{}) error { return s.services.registerName(name, receiver) } +// RegisterDenyList add given method name to the deny list so that RPC requests that matches +// any of the methods in deny list will got rejected directly. +func (s *Server) RegisterDenyList(methodName string) { + s.denyList[methodName] = struct{}{} +} + // ServeCodec reads incoming requests from codec, calls the appropriate callback and writes // the response back using the given codec. It will block until the codec is closed or the // server is stopped. In either case the codec is closed. @@ -141,6 +150,7 @@ func (s *Server) serveSingleRequest(ctx context.Context, codec ServerCodec) { defer h.close(io.EOF, nil) reqs, batch, err := codec.readBatch() + if err != nil { if err != io.EOF { resp := errorMessage(&invalidMessageError{"parse error"}) @@ -148,6 +158,15 @@ func (s *Server) serveSingleRequest(ctx context.Context, codec ServerCodec) { } return } + // check deny list + for _, req := range reqs { + method := req.Method + if _, found := s.denyList[method]; found { + resp := errorMessage(&invalidMessageError{fmt.Sprintf("method %s is in deny list", method)}) + codec.writeJSON(ctx, resp, true) + return + } + } if batch { h.handleBatch(reqs) } else { From 8c577d58294d3b8e1d6dbbae3101c9036fbab3e3 Mon Sep 17 00:00:00 2001 From: yzang2019 Date: Tue, 12 Mar 2024 13:39:24 +0800 Subject: [PATCH 2/3] Change error type to methodNotFoundError --- rpc/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/server.go b/rpc/server.go index b34cefc677..5cee52d21b 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -162,7 +162,7 @@ func (s *Server) serveSingleRequest(ctx context.Context, codec ServerCodec) { for _, req := range reqs { method := req.Method if _, found := s.denyList[method]; found { - resp := errorMessage(&invalidMessageError{fmt.Sprintf("method %s is in deny list", method)}) + resp := errorMessage(&methodNotFoundError{fmt.Sprintf("method %s is in deny list", method)}) codec.writeJSON(ctx, resp, true) return } From c27c86e2955a1f1944b8deeda657691f122b1a39 Mon Sep 17 00:00:00 2001 From: yzang2019 Date: Tue, 12 Mar 2024 15:18:11 +0800 Subject: [PATCH 3/3] Fix error code --- rpc/server.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rpc/server.go b/rpc/server.go index 5cee52d21b..a97c927757 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -18,7 +18,6 @@ package rpc import ( "context" - "fmt" "io" "sync" "sync/atomic" @@ -162,7 +161,7 @@ func (s *Server) serveSingleRequest(ctx context.Context, codec ServerCodec) { for _, req := range reqs { method := req.Method if _, found := s.denyList[method]; found { - resp := errorMessage(&methodNotFoundError{fmt.Sprintf("method %s is in deny list", method)}) + resp := errorMessage(&methodNotFoundError{method: method}) codec.writeJSON(ctx, resp, true) return }