From a903912b9622780a7b6d852a21307a8a81962fd7 Mon Sep 17 00:00:00 2001
From: Felix Lange <fjl@twurst.com>
Date: Tue, 28 Jan 2020 10:37:08 +0100
Subject: [PATCH] rpc: check module availability at startup (#20597)

Fixes #20467

Co-authored-by: meowsbits <45600330+meowsbits@users.noreply.github.com>
---
 cmd/geth/config.go |  4 ++--
 rpc/endpoints.go   | 34 +++++++++++++++++++++++++++++++---
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/cmd/geth/config.go b/cmd/geth/config.go
index b450dd9c8..71e835534 100644
--- a/cmd/geth/config.go
+++ b/cmd/geth/config.go
@@ -99,8 +99,8 @@ func defaultNodeConfig() node.Config {
 	cfg := node.DefaultConfig
 	cfg.Name = clientIdentifier
 	cfg.Version = params.VersionWithCommit(gitCommit, gitDate)
-	cfg.HTTPModules = append(cfg.HTTPModules, "eth", "shh")
-	cfg.WSModules = append(cfg.WSModules, "eth", "shh")
+	cfg.HTTPModules = append(cfg.HTTPModules, "eth")
+	cfg.WSModules = append(cfg.WSModules, "eth")
 	cfg.IPCPath = "geth.ipc"
 	return cfg
 }
diff --git a/rpc/endpoints.go b/rpc/endpoints.go
index 8ca6d4eb0..2cf51aedf 100644
--- a/rpc/endpoints.go
+++ b/rpc/endpoints.go
@@ -17,13 +17,39 @@
 package rpc
 
 import (
+	"fmt"
 	"net"
 
 	"github.com/ethereum/go-ethereum/log"
 )
 
-// StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules
+// checkModuleAvailability check that all names given in modules are actually
+// available API services.
+func checkModuleAvailability(modules []string, apis []API) error {
+	available := make(map[string]struct{})
+	var availableNames string
+	for i, api := range apis {
+		if _, ok := available[api.Namespace]; !ok {
+			available[api.Namespace] = struct{}{}
+			if i > 0 {
+				availableNames += ", "
+			}
+			availableNames += api.Namespace
+		}
+	}
+	for _, name := range modules {
+		if _, ok := available[name]; !ok {
+			return fmt.Errorf("invalid API %q in whitelist (available: %s)", name, availableNames)
+		}
+	}
+	return nil
+}
+
+// StartHTTPEndpoint starts the HTTP RPC endpoint, configured with cors/vhosts/modules.
 func StartHTTPEndpoint(endpoint string, apis []API, modules []string, cors []string, vhosts []string, timeouts HTTPTimeouts) (net.Listener, *Server, error) {
+	if err := checkModuleAvailability(modules, apis); err != nil {
+		return nil, nil, err
+	}
 	// Generate the whitelist based on the allowed modules
 	whitelist := make(map[string]bool)
 	for _, module := range modules {
@@ -51,9 +77,11 @@ func StartHTTPEndpoint(endpoint string, apis []API, modules []string, cors []str
 	return listener, handler, err
 }
 
-// StartWSEndpoint starts a websocket endpoint
+// StartWSEndpoint starts a websocket endpoint.
 func StartWSEndpoint(endpoint string, apis []API, modules []string, wsOrigins []string, exposeAll bool) (net.Listener, *Server, error) {
-
+	if err := checkModuleAvailability(modules, apis); err != nil {
+		return nil, nil, err
+	}
 	// Generate the whitelist based on the allowed modules
 	whitelist := make(map[string]bool)
 	for _, module := range modules {
-- 
GitLab