From 4d660e30b12dd1a06205c0e37800c61a0cb1bbef Mon Sep 17 00:00:00 2001 From: marcello33 Date: Thu, 31 Oct 2024 10:56:15 +0100 Subject: [PATCH 1/3] chg: some sec fixes --- .../setu/listener/rootchain_selfheal_graph.go | 7 +++++- bridge/setu/processor/base.go | 8 ++++--- bridge/setu/util/common.go | 6 +++-- helper/call.go | 9 +++++--- helper/util.go | 23 +++++++++++++++---- types/rest/rest.go | 6 ++++- 6 files changed, 44 insertions(+), 15 deletions(-) diff --git a/bridge/setu/listener/rootchain_selfheal_graph.go b/bridge/setu/listener/rootchain_selfheal_graph.go index 736f4bc99..dcd5d5b49 100644 --- a/bridge/setu/listener/rootchain_selfheal_graph.go +++ b/bridge/setu/listener/rootchain_selfheal_graph.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/maticnetwork/heimdall/helper" "io" "math/big" "net/http" @@ -42,6 +43,7 @@ type stateSyncResponse struct { } `json:"data"` } +// querySubGraph queries the subgraph and limits the read size func (rl *RootChainListener) querySubGraph(query []byte, ctx context.Context) (data []byte, err error) { request, err := http.NewRequestWithContext(ctx, http.MethodPost, rl.subGraphClient.graphUrl, bytes.NewBuffer(query)) if err != nil { @@ -56,7 +58,10 @@ func (rl *RootChainListener) querySubGraph(query []byte, ctx context.Context) (d } defer response.Body.Close() - return io.ReadAll(response.Body) + // Limit the number of bytes read from the response body + limitedBody := http.MaxBytesReader(nil, response.Body, helper.APIBodyLimit) + + return io.ReadAll(limitedBody) } // getLatestStateID returns state ID from the latest StateSynced event diff --git a/bridge/setu/processor/base.go b/bridge/setu/processor/base.go index f33b4e357..5505463dc 100644 --- a/bridge/setu/processor/base.go +++ b/bridge/setu/processor/base.go @@ -162,12 +162,14 @@ func (bp *BaseProcessor) checkTxAgainstMempool(msg types.Msg, event interface{}) bp.Logger.Error("Error fetching mempool tx", "url", endpoint, "error", err) return false, err } - - body, err := io.ReadAll(resp.Body) defer resp.Body.Close() + // Limit the number of bytes read from the response body + limitedBody := http.MaxBytesReader(nil, resp.Body, helper.APIBodyLimit) + + body, err := io.ReadAll(limitedBody) if err != nil { - bp.Logger.Error("Error fetching mempool tx", "error", err) + bp.Logger.Error("Error reading response body for mempool tx", "error", err) return false, err } diff --git a/bridge/setu/util/common.go b/bridge/setu/util/common.go index d8173b004..12a4ae108 100644 --- a/bridge/setu/util/common.go +++ b/bridge/setu/util/common.go @@ -652,10 +652,12 @@ func GetUnconfirmedTxnCount(event interface{}) int { logger.Error("Error fetching mempool txs count", "url", endpoint, "error", err) return 0 } - - body, err := io.ReadAll(resp.Body) defer resp.Body.Close() + // Limit the number of bytes read from the response body + limitedBody := http.MaxBytesReader(nil, resp.Body, helper.APIBodyLimit) + + body, err := io.ReadAll(limitedBody) if err != nil { logger.Error("Error fetching mempool txs count", "error", err) return 0 diff --git a/helper/call.go b/helper/call.go index dca52bece..75424a496 100644 --- a/helper/call.go +++ b/helper/call.go @@ -310,10 +310,10 @@ func (c *ContractCaller) GetRootHash(start uint64, end uint64, checkpointLength return common.FromHex(rootHash), nil } -// GetRootHash get root hash from bor chain +// GetVoteOnHash gets vote on hash from bor chain func (c *ContractCaller) GetVoteOnHash(start uint64, end uint64, milestoneLength uint64, hash string, milestoneID string) (bool, error) { if start > end { - return false, errors.New("Start block number is greater than the end block number") + return false, errors.New("start block number is greater than the end block number") } ctx, cancel := context.WithTimeout(context.Background(), c.MaticChainTimeout) @@ -368,7 +368,7 @@ func (c *ContractCaller) GetValidatorInfo(valID types.ValidatorID, stakingInfoIn // amount, startEpoch, endEpoch, signer, status, err := c.StakingInfoInstance.GetStakerDetails(nil, big.NewInt(int64(valID))) stakerDetails, err := stakingInfoInstance.GetStakerDetails(nil, big.NewInt(int64(valID))) if err != nil { - Logger.Error("Error fetching validator information from stake manager", "validatorId", valID, "status", stakerDetails.Status, "error", err) + Logger.Error("Error fetching validator information from stake manager", "validatorId", valID, "error", err) return } @@ -814,6 +814,9 @@ func (c *ContractCaller) GetSpanDetails(id *big.Int, validatorSetInstance *valid error, ) { d, err := validatorSetInstance.GetSpan(nil, id) + if err != nil { + return nil, nil, nil, err + } return d.Number, d.StartBlock, d.EndBlock, err } diff --git a/helper/util.go b/helper/util.go index e3f41956e..4336fb85a 100644 --- a/helper/util.go +++ b/helper/util.go @@ -42,6 +42,8 @@ import ( "github.com/maticnetwork/heimdall/types/rest" ) +const APIBodyLimit = 128 * 1024 * 1024 // 128 MB + //go:generate mockgen -destination=./mocks/http_client_mock.go -package=mocks . HTTPClient type HTTPClient interface { Get(string) (resp *http.Response, err error) @@ -567,10 +569,18 @@ func SignStdTx(cliCtx context.CLIContext, stdTx authTypes.StdTx, appendSig bool, // ReadStdTxFromFile and decode a StdTx from the given filename. Can pass "-" to read from stdin. func ReadStdTxFromFile(cdc *amino.Codec, filename string) (stdTx authTypes.StdTx, err error) { var bytes []byte + if filename == "-" { - bytes, err = io.ReadAll(os.Stdin) + limitedReader := &io.LimitedReader{R: os.Stdin, N: APIBodyLimit} + bytes, err = io.ReadAll(limitedReader) } else { - bytes, err = os.ReadFile(filename) + file, err := os.Open(filename) + if err != nil { + return + } + defer file.Close() + limitedReader := &io.LimitedReader{R: file, N: APIBodyLimit} + bytes, err = io.ReadAll(limitedReader) } if err != nil { @@ -802,7 +812,7 @@ func GetHeimdallServerEndpoint(endpoint string) string { return u.String() } -// FetchFromAPI fetches data from any URL +// FetchFromAPI fetches data from any URL with limited read size func FetchFromAPI(cliCtx cliContext.CLIContext, URL string) (result rest.ResponseWithHeight, err error) { resp, err := Client.Get(URL) if err != nil { @@ -811,9 +821,12 @@ func FetchFromAPI(cliCtx cliContext.CLIContext, URL string) (result rest.Respons defer resp.Body.Close() - // response + // Limit the number of bytes read from the response body + limitedBody := http.MaxBytesReader(nil, resp.Body, APIBodyLimit) + + // Handle the response if resp.StatusCode == 200 { - body, err := io.ReadAll(resp.Body) + body, err := io.ReadAll(limitedBody) if err != nil { return result, err } diff --git a/types/rest/rest.go b/types/rest/rest.go index 622e743cb..850d00ae6 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "github.com/maticnetwork/heimdall/helper" "io" "net/http" "net/url" @@ -128,7 +129,10 @@ func (br BaseReq) ValidateBasic(w http.ResponseWriter) bool { // ReadRESTReq reads and unmarshals a Request's body to the BaseReq struct. // Writes an error response to ResponseWriter and returns true if errors occurred. func ReadRESTReq(w http.ResponseWriter, r *http.Request, cdc *codec.Codec, req interface{}) bool { - body, err := io.ReadAll(r.Body) + // Limit the number of bytes read from the request body + limitedBody := http.MaxBytesReader(w, r.Body, helper.APIBodyLimit) + + body, err := io.ReadAll(limitedBody) if err != nil { WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return false From 62cf3325cdc2de95e0f3460983db33da63e8ea25 Mon Sep 17 00:00:00 2001 From: marcello33 Date: Thu, 31 Oct 2024 11:43:20 +0100 Subject: [PATCH 2/3] chg: resolve dep cycle --- helper/util.go | 5 +++-- types/rest/rest.go | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/helper/util.go b/helper/util.go index 4336fb85a..5e17674d7 100644 --- a/helper/util.go +++ b/helper/util.go @@ -574,8 +574,9 @@ func ReadStdTxFromFile(cdc *amino.Codec, filename string) (stdTx authTypes.StdTx limitedReader := &io.LimitedReader{R: os.Stdin, N: APIBodyLimit} bytes, err = io.ReadAll(limitedReader) } else { - file, err := os.Open(filename) - if err != nil { + file, er := os.Open(filename) + if er != nil { + err = er return } defer file.Close() diff --git a/types/rest/rest.go b/types/rest/rest.go index 850d00ae6..92f1cfe9e 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -6,7 +6,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/maticnetwork/heimdall/helper" "io" "net/http" "net/url" @@ -24,7 +23,8 @@ import ( const ( DefaultPage = 1 - DefaultLimit = 30 // should be consistent with tendermint/tendermint/rpc/core/pipe.go:19 + DefaultLimit = 30 // should be consistent with tendermint/tendermint/rpc/core/pipe.go:19 + APIBodyLimit = 128 * 1024 * 1024 // 128 MB ) var ( @@ -130,7 +130,7 @@ func (br BaseReq) ValidateBasic(w http.ResponseWriter) bool { // Writes an error response to ResponseWriter and returns true if errors occurred. func ReadRESTReq(w http.ResponseWriter, r *http.Request, cdc *codec.Codec, req interface{}) bool { // Limit the number of bytes read from the request body - limitedBody := http.MaxBytesReader(w, r.Body, helper.APIBodyLimit) + limitedBody := http.MaxBytesReader(w, r.Body, APIBodyLimit) body, err := io.ReadAll(limitedBody) if err != nil { From 9994ce2c705633ae5e6998b9e392548bd5e081fb Mon Sep 17 00:00:00 2001 From: marcello33 Date: Thu, 31 Oct 2024 12:32:19 +0100 Subject: [PATCH 3/3] chg: sort imports --- bridge/setu/listener/rootchain_selfheal_graph.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bridge/setu/listener/rootchain_selfheal_graph.go b/bridge/setu/listener/rootchain_selfheal_graph.go index dcd5d5b49..43542c7f0 100644 --- a/bridge/setu/listener/rootchain_selfheal_graph.go +++ b/bridge/setu/listener/rootchain_selfheal_graph.go @@ -5,7 +5,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/maticnetwork/heimdall/helper" "io" "math/big" "net/http" @@ -15,6 +14,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" jsoniter "github.com/json-iterator/go" + + "github.com/maticnetwork/heimdall/helper" ) // StakeUpdate represents the StakeUpdate event