From 48a92a171cfc9e2f55dc275a5d6bf293bd3589cf Mon Sep 17 00:00:00 2001 From: John | Elite Encoder Date: Thu, 5 Sep 2024 08:59:55 -0400 Subject: [PATCH] validate `-serviceAddr` on startup and cli handler (#3156) --- cmd/livepeer/starter/starter.go | 5 +++++ common/util.go | 5 +++++ common/util_test.go | 36 +++++++++++++++++++++++++++++++++ server/handlers.go | 6 ++++++ server/handlers_test.go | 23 +++++++++++++++++++++ 5 files changed, 75 insertions(+) diff --git a/cmd/livepeer/starter/starter.go b/cmd/livepeer/starter/starter.go index 1556b125df..fb153b3802 100755 --- a/cmd/livepeer/starter/starter.go +++ b/cmd/livepeer/starter/starter.go @@ -1199,6 +1199,11 @@ func StartLivepeer(ctx context.Context, cfg LivepeerConfig) { if err != nil { glog.Exit("Error getting service URI: ", err) } + + if *cfg.Network != "offchain" && !common.ValidateServiceURI(suri) { + glog.Warning("**Warning -serviceAddr is a not a public address or hostname; this is not recommended for onchain networks**") + } + n.SetServiceURI(suri) // if http addr is not provided, listen to all ifaces // take the port to listen to from the service URI diff --git a/common/util.go b/common/util.go index 639cf07ccd..b4d7396a8b 100644 --- a/common/util.go +++ b/common/util.go @@ -11,6 +11,7 @@ import ( "math/big" "math/rand" "mime" + "net/url" "regexp" "sort" "strconv" @@ -530,3 +531,7 @@ func ParseEthAddr(strJsonKey string) (string, error) { } return "", errors.New("Error parsing address from keyfile") } + +func ValidateServiceURI(serviceURI *url.URL) bool { + return !strings.Contains(serviceURI.Host, "0.0.0.0") +} diff --git a/common/util_test.go b/common/util_test.go index 9a541669d6..131631586e 100644 --- a/common/util_test.go +++ b/common/util_test.go @@ -5,6 +5,7 @@ import ( "fmt" "math" "math/big" + "net/url" "strconv" "strings" "testing" @@ -483,3 +484,38 @@ func TestParseAccelDevices_CustomSelection(t *testing.T) { assert.Equal(ids[1], "3") assert.Equal(ids[2], "1") } +func TestValidateServiceURI(t *testing.T) { + // Valid service URIs + validURIs := []string{ + "https://8.8.8.8:8935", + "https://127.0.0.1:8935", + } + + for _, uri := range validURIs { + serviceURI, err := url.Parse(uri) + if err != nil { + t.Errorf("Failed to parse valid service URI: %v", err) + } + + if !ValidateServiceURI(serviceURI) { + t.Errorf("Expected service URI to be valid, but got invalid: %v", uri) + } + } + + // Invalid service URIs + invalidURIs := []string{ + "http://0.0.0.0", + "https://0.0.0.0", + } + + for _, uri := range invalidURIs { + serviceURI, err := url.Parse(uri) + if err != nil { + t.Errorf("Failed to parse invalid service URI: %v", err) + } + + if ValidateServiceURI(serviceURI) { + t.Errorf("Expected service URI to be invalid, but got valid: %v", uri) + } + } +} diff --git a/server/handlers.go b/server/handlers.go index 22116079e6..5e9cc62d8c 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -526,6 +526,12 @@ func (s *LivepeerServer) setServiceURI(client eth.LivepeerEthClient, serviceURI return err } + if !common.ValidateServiceURI(parsedURI) { + err = errors.New("service address must be a public IP address or hostname") + glog.Error(err) + return err + } + glog.Infof("Storing service URI %v in service registry...", serviceURI) tx, err := client.SetServiceURI(serviceURI) diff --git a/server/handlers_test.go b/server/handlers_test.go index d191d0a75e..528282972e 100644 --- a/server/handlers_test.go +++ b/server/handlers_test.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/accounts" ethcommon "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/livepeer/go-livepeer/core" "github.com/livepeer/go-livepeer/eth" "github.com/livepeer/go-livepeer/eth/types" @@ -1570,7 +1571,29 @@ func TestMustHaveDb_Success(t *testing.T) { assert.Equal(http.StatusOK, status) assert.Equal("success", body) } +func TestSetServiceURI(t *testing.T) { + s := stubServer() + client := ð.MockClient{} + serviceURI := "https://8.8.8.8:8935" + + t.Run("Valid Service URI", func(t *testing.T) { + client.On("SetServiceURI", serviceURI).Return(ðtypes.Transaction{}, nil) + client.On("CheckTx", mock.Anything).Return(nil) + + err := s.setServiceURI(client, serviceURI) + + assert.NoError(t, err) + }) + t.Run("Invalid Service URI", func(t *testing.T) { + invalidServiceURI := "https://0.0.0.0:8935" + + err := s.setServiceURI(client, invalidServiceURI) + + assert.Error(t, err) + }) + +} func dummyHandler() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK)