From ae82c4cd373b31a2f9d3c438158269044a65af59 Mon Sep 17 00:00:00 2001
From: Jaynti Kanani <jdkanani@gmail.com>
Date: Wed, 25 Mar 2020 18:41:16 +0530
Subject: [PATCH] fix polluted path and check data length for validation action

---
 consensus/bor/bor.go  |  8 ++++++++
 consensus/bor/rest.go | 36 +++++++++++++++++++++---------------
 2 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go
index d84288d42..406989b6c 100644
--- a/consensus/bor/bor.go
+++ b/consensus/bor/bor.go
@@ -1253,6 +1253,10 @@ func (c *Bor) IsValidatorAction(chain consensus.ChainReader, from common.Address
 func isProposeSpanAction(tx *types.Transaction, validatorContract string) bool {
 	// keccak256('proposeSpan()').slice(0, 4)
 	proposeSpanSig, _ := hex.DecodeString("4b0e4d17")
+	if tx.Data() == nil || len(tx.Data()) < 4 {
+		return false
+	}
+
 	return bytes.Compare(proposeSpanSig, tx.Data()[:4]) == 0 &&
 		tx.To().String() == validatorContract
 }
@@ -1260,6 +1264,10 @@ func isProposeSpanAction(tx *types.Transaction, validatorContract string) bool {
 func isProposeStateAction(tx *types.Transaction, stateReceiverContract string) bool {
 	// keccak256('proposeState(uint256)').slice(0, 4)
 	proposeStateSig, _ := hex.DecodeString("ede01f17")
+	if tx.Data() == nil || len(tx.Data()) < 4 {
+		return false
+	}
+
 	return bytes.Compare(proposeStateSig, tx.Data()[:4]) == 0 &&
 		tx.To().String() == stateReceiverContract
 }
diff --git a/consensus/bor/rest.go b/consensus/bor/rest.go
index 6129037fc..9c525d6df 100644
--- a/consensus/bor/rest.go
+++ b/consensus/bor/rest.go
@@ -25,18 +25,13 @@ type IHeimdallClient interface {
 }
 
 type HeimdallClient struct {
-	u      *url.URL
-	client http.Client
+	urlString string
+	client    http.Client
 }
 
 func NewHeimdallClient(urlString string) (*HeimdallClient, error) {
-	u, err := url.Parse(urlString)
-	if err != nil {
-		return nil, err
-	}
-
 	h := &HeimdallClient{
-		u: u,
+		urlString: urlString,
 		client: http.Client{
 			Timeout: time.Duration(5 * time.Second),
 		},
@@ -45,35 +40,46 @@ func NewHeimdallClient(urlString string) (*HeimdallClient, error) {
 }
 
 func (h *HeimdallClient) Fetch(paths ...string) (*ResponseWithHeight, error) {
+	u, err := url.Parse(h.urlString)
+	if err != nil {
+		return nil, err
+	}
+
 	for _, e := range paths {
 		if e != "" {
-			h.u.Path = path.Join(h.u.Path, e)
+			u.Path = path.Join(u.Path, e)
 		}
 	}
-	return h.internalFetch()
+
+	return h.internalFetch(u)
 }
 
 // FetchWithRetry returns data from heimdall with retry
 func (h *HeimdallClient) FetchWithRetry(paths ...string) (*ResponseWithHeight, error) {
+	u, err := url.Parse(h.urlString)
+	if err != nil {
+		return nil, err
+	}
+
 	for _, e := range paths {
 		if e != "" {
-			h.u.Path = path.Join(h.u.Path, e)
+			u.Path = path.Join(u.Path, e)
 		}
 	}
 
 	for {
-		res, err := h.internalFetch()
+		res, err := h.internalFetch(u)
 		if err == nil && res != nil {
 			return res, nil
 		}
-		log.Info("Retrying again in 5 seconds for next Heimdall span", "path", h.u.Path)
+		log.Info("Retrying again in 5 seconds for next Heimdall span", "path", u.Path)
 		time.Sleep(5 * time.Second)
 	}
 }
 
 // internal fetch method
-func (h *HeimdallClient) internalFetch() (*ResponseWithHeight, error) {
-	res, err := h.client.Get(h.u.String())
+func (h *HeimdallClient) internalFetch(u *url.URL) (*ResponseWithHeight, error) {
+	res, err := h.client.Get(u.String())
 	if err != nil {
 		return nil, err
 	}
-- 
GitLab