From f5193f432df55da4059813b4c67ec81c3e11285d Mon Sep 17 00:00:00 2001 From: spletka Date: Wed, 6 Sep 2023 12:01:37 +0200 Subject: [PATCH 1/4] (BIDS-2417) Changed wrong user input to warnings --- db/db.go | 2 +- handlers/common.go | 4 +- handlers/dashboard.go | 8 +-- handlers/epochs.go | 12 ++-- handlers/eth1Blocks.go | 12 ++-- handlers/eth1Deposits.go | 24 ++++---- handlers/eth1tx.go | 2 +- handlers/eth2Deposits.go | 12 ++-- handlers/graffitiwall.go | 3 +- handlers/pools_rocketpool.go | 76 ++++++++++++++++-------- handlers/slot.go | 24 ++++---- handlers/slots.go | 12 ++-- handlers/user.go | 34 +++-------- handlers/validator.go | 93 +++++++++++++++--------------- handlers/validatorRewards.go | 48 ++++++++------- handlers/validators.go | 10 ++-- handlers/validators_leaderboard.go | 12 ++-- handlers/validators_slashings.go | 12 ++-- handlers/vis.go | 8 +++ handlers/withdrawals.go | 24 ++++---- services/rewards.go | 4 +- utils/utils.go | 20 ++++++- 22 files changed, 249 insertions(+), 207 deletions(-) diff --git a/db/db.go b/db/db.go index 9d4306aa94..ba88355f28 100644 --- a/db/db.go +++ b/db/db.go @@ -1662,7 +1662,7 @@ func saveBlocks(blocks map[uint64]map[string]*types.Block, tx *sqlx.Tx, forceSlo b.Signature, b.RandaoReveal, b.Graffiti, - utils.GraffitiToSring(b.Graffiti), + utils.GraffitiToString(b.Graffiti), b.Eth1Data.DepositRoot, b.Eth1Data.DepositCount, b.Eth1Data.BlockHash, diff --git a/handlers/common.go b/handlers/common.go index 05aa819714..be4caa7c50 100644 --- a/handlers/common.go +++ b/handlers/common.go @@ -621,8 +621,8 @@ func SetDataTableStateChanges(w http.ResponseWriter, r *http.Request) { settings := types.DataTableSaveState{} err = json.NewDecoder(r.Body).Decode(&settings) if err != nil { - utils.LogError(err, errMsgPrefix+", could not parse body", 0, errFields) - w.WriteHeader(http.StatusInternalServerError) + logger.Warnf(errMsgPrefix+", could not parse body for tableKey %v: %v", tableKey, err) + w.WriteHeader(http.StatusBadRequest) return } diff --git a/handlers/dashboard.go b/handlers/dashboard.go index 51729652a9..1575e49da5 100644 --- a/handlers/dashboard.go +++ b/handlers/dashboard.go @@ -648,14 +648,14 @@ func DashboardDataWithdrawals(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - utils.LogError(err, fmt.Errorf("error converting datatables data parameter from string to int: %v", err), 0) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - utils.LogError(err, fmt.Errorf("error converting datatables data parameter from string to int: %v", err), 0) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } diff --git a/handlers/epochs.go b/handlers/epochs.go index 9e2a10c32f..4b1d4e4e0c 100644 --- a/handlers/epochs.go +++ b/handlers/epochs.go @@ -42,20 +42,20 @@ func EpochsData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { diff --git a/handlers/eth1Blocks.go b/handlers/eth1Blocks.go index 363d3c79bd..78f4078b6d 100644 --- a/handlers/eth1Blocks.go +++ b/handlers/eth1Blocks.go @@ -42,20 +42,20 @@ func Eth1BlocksData(w http.ResponseWriter, r *http.Request) { } draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int for route %v: %v", r.URL.String(), err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int for route %v: %v", r.URL.String(), err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int for route %v: %v", r.URL.String(), err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int for route %v: %v", r.URL.String(), err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int for route %v: %v", r.URL.String(), err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int for route %v: %v", r.URL.String(), err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { diff --git a/handlers/eth1Deposits.go b/handlers/eth1Deposits.go index a4ee7196cf..6a4fad5501 100644 --- a/handlers/eth1Deposits.go +++ b/handlers/eth1Deposits.go @@ -59,20 +59,20 @@ func Eth1DepositsData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { @@ -171,20 +171,20 @@ func Eth1DepositsLeaderboardData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { diff --git a/handlers/eth1tx.go b/handlers/eth1tx.go index 3b6c2cb0a2..228e3f1589 100644 --- a/handlers/eth1tx.go +++ b/handlers/eth1tx.go @@ -42,7 +42,7 @@ func Eth1TransactionTx(w http.ResponseWriter, r *http.Request) { txHash, err := hex.DecodeString(strings.ReplaceAll(txHashString, "0x", "")) if err != nil { - logger.Errorf("error parsing tx hash %v: %v", txHashString, err) + logger.Warnf("error parsing tx hash %v: %v", txHashString, err) data = InitPageData(w, r, "blockchain", path, title, txNotFoundTemplateFiles) txTemplate = txNotFoundTemplate } else { diff --git a/handlers/eth2Deposits.go b/handlers/eth2Deposits.go index ae3883da90..032b1deb14 100644 --- a/handlers/eth2Deposits.go +++ b/handlers/eth2Deposits.go @@ -27,20 +27,20 @@ func Eth2DepositsData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { diff --git a/handlers/graffitiwall.go b/handlers/graffitiwall.go index 7e861bedc0..6462b2b5b9 100644 --- a/handlers/graffitiwall.go +++ b/handlers/graffitiwall.go @@ -4,6 +4,7 @@ import ( "eth2-exporter/db" "eth2-exporter/templates" "eth2-exporter/types" + "eth2-exporter/utils" "net/http" ) @@ -21,7 +22,7 @@ func Graffitiwall(w http.ResponseWriter, r *http.Request) { err = db.ReaderDb.Select(&graffitiwallData, "SELECT DISTINCT ON (x, y) x, y, color, slot, validator from graffitiwall ORDER BY x, y, slot DESC") if err != nil { - logger.Errorf("error retrieving block tree data: %v", err) + utils.LogError(err, "error retrieving graffitiwall data", 0) http.Error(w, "Internal server error", http.StatusServiceUnavailable) return } diff --git a/handlers/pools_rocketpool.go b/handlers/pools_rocketpool.go index dc174e96d5..e2e2c3797e 100644 --- a/handlers/pools_rocketpool.go +++ b/handlers/pools_rocketpool.go @@ -32,20 +32,20 @@ func PoolsRocketpoolDataMinipools(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { @@ -56,6 +56,13 @@ func PoolsRocketpoolDataMinipools(w http.ResponseWriter, r *http.Request) { search = search[:128] } + // Search for invalid postgres strings + if utils.HasProblematicUtfCharacters(search) || strings.HasSuffix(search, "\\") { + logger.Warnf("error converting search %v to valid UTF-8): %v", search, err) + http.Error(w, "Error: Invalid parameter search.", http.StatusBadRequest) + return + } + orderColumn := q.Get("order[0][column]") orderByMap := map[string]string{ "0": "address", @@ -188,20 +195,20 @@ func PoolsRocketpoolDataNodes(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { @@ -212,6 +219,13 @@ func PoolsRocketpoolDataNodes(w http.ResponseWriter, r *http.Request) { search = search[:128] } + // Search for invalid postgres strings + if utils.HasProblematicUtfCharacters(search) || strings.HasSuffix(search, "\\") { + logger.Warnf("error converting search %v to valid UTF-8): %v", search, err) + http.Error(w, "Error: Invalid parameter search.", http.StatusBadRequest) + return + } + orderColumn := q.Get("order[0][column]") orderByMap := map[string]string{ "0": "address", @@ -332,20 +346,20 @@ func PoolsRocketpoolDataDAOProposals(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { @@ -356,6 +370,13 @@ func PoolsRocketpoolDataDAOProposals(w http.ResponseWriter, r *http.Request) { search = search[:128] } + // Search for invalid postgres strings + if utils.HasProblematicUtfCharacters(search) || strings.HasSuffix(search, "\\") { + logger.Warnf("error converting search %v to valid UTF-8): %v", search, err) + http.Error(w, "Error: Invalid parameter search.", http.StatusBadRequest) + return + } + orderColumn := q.Get("order[0][column]") orderByMap := map[string]string{ "0": "id", @@ -545,20 +566,20 @@ func PoolsRocketpoolDataDAOMembers(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { @@ -569,6 +590,13 @@ func PoolsRocketpoolDataDAOMembers(w http.ResponseWriter, r *http.Request) { search = search[:128] } + // Search for invalid postgres strings + if utils.HasProblematicUtfCharacters(search) || strings.HasSuffix(search, "\\") { + logger.Warnf("error converting search %v to valid UTF-8): %v", search, err) + http.Error(w, "Error: Invalid parameter search.", http.StatusBadRequest) + return + } + orderColumn := q.Get("order[0][column]") orderByMap := map[string]string{ "0": "address", diff --git a/handlers/slot.go b/handlers/slot.go index f2a436f8f1..39bc14d641 100644 --- a/handlers/slot.go +++ b/handlers/slot.go @@ -452,21 +452,21 @@ func SlotDepositData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } @@ -582,21 +582,21 @@ func SlotVoteData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } diff --git a/handlers/slots.go b/handlers/slots.go index 070cfb1ab3..613c178980 100644 --- a/handlers/slots.go +++ b/handlers/slots.go @@ -47,20 +47,20 @@ func SlotsData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } diff --git a/handlers/user.go b/handlers/user.go index fe371b2603..b469c847e1 100644 --- a/handlers/user.go +++ b/handlers/user.go @@ -907,25 +907,10 @@ func UserNotificationsData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } - // start, err := strconv.ParseUint(q.Get("start"), 10, 64) - // if err != nil { - // logger.Errorf("error converting datatables start parameter from string to int: %v", err) - // http.Error(w, "Internal server error", http.StatusServiceUnavailable) - // return - // } - // length, err := strconv.ParseUint(q.Get("length"), 10, 64) - // if err != nil { - // logger.Errorf("error converting datatables length parameter from string to int: %v", err) - // http.Error(w, "Internal server error", http.StatusServiceUnavailable) - // return - // } - // if length > 100 { - // length = 100 - // } user := getUser(r) @@ -1020,20 +1005,15 @@ func UserSubscriptionsData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } - // start, err := strconv.ParseUint(q.Get("start"), 10, 64) - // if err != nil { - // logger.Errorf("error converting datatables start parameter from string to int: %v", err) - // http.Error(w, "Internal server error", http.StatusServiceUnavailable) - // return - // } + length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { diff --git a/handlers/validator.go b/handlers/validator.go index 967dcc9358..6f04731e0d 100644 --- a/handlers/validator.go +++ b/handlers/validator.go @@ -14,6 +14,7 @@ import ( "eth2-exporter/utils" "fmt" "html/template" + "math" "math/big" "net/http" "sort" @@ -243,7 +244,7 @@ func Validator(w http.ResponseWriter, r *http.Request) { } else { // Request came with a validator index number index, err = strconv.ParseUint(vars["index"], 10, 64) - if err != nil { + if err != nil || index > math.MaxInt32 { // index in postgres is limited to int validatorNotFound(data, w, r, vars, "") return } @@ -874,9 +875,9 @@ func ValidatorAttestationInclusionEffectiveness(w http.ResponseWriter, r *http.R vars := mux.Vars(r) index, err := strconv.ParseUint(vars["index"], 10, 64) - if err != nil { - logger.Errorf("error parsing validator index: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + if err != nil || index > math.MaxInt32 { // index in postgres is limited to int + logger.Warnf("error parsing validator index: %v", err) + http.Error(w, "Error: Invalid parameter validator index.", http.StatusBadRequest) return } @@ -919,9 +920,9 @@ func ValidatorProposedBlocks(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) index, err := strconv.ParseUint(vars["index"], 10, 64) - if err != nil { - logger.Errorf("error parsing validator index: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + if err != nil || index > math.MaxInt32 { // index in postgres is limited to int + logger.Warnf("error parsing validator index: %v", err) + http.Error(w, "Error: Invalid parameter validator index.", http.StatusBadRequest) return } @@ -929,20 +930,20 @@ func ValidatorProposedBlocks(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { @@ -1040,9 +1041,9 @@ func ValidatorAttestations(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) index, err := strconv.ParseUint(vars["index"], 10, 64) - if err != nil { - logger.Errorf("error parsing validator index: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + if err != nil || index > math.MaxInt32 { // index in postgres is limited to int + logger.Warnf("error parsing validator index: %v", err) + http.Error(w, "Error: Invalid parameter validator index.", http.StatusBadRequest) return } @@ -1050,14 +1051,14 @@ func ValidatorAttestations(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseInt(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } @@ -1093,7 +1094,7 @@ func ValidatorAttestations(w http.ResponseWriter, r *http.Request) { endEpoch := uint64(int64(lastAttestationEpoch) - start) attestationData, err := db.BigtableClient.GetValidatorAttestationHistory([]uint64{index}, endEpoch-uint64(length)+1, endEpoch) if err != nil { - logger.Errorf("error retrieving validator attestations data: %v", err) + logger.Errorf("error retrieving bigtable validator attestations data: %v", err) http.Error(w, "Internal server error", http.StatusInternalServerError) return } @@ -1137,9 +1138,9 @@ func ValidatorWithdrawals(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) index, err := strconv.ParseUint(vars["index"], 10, 64) - if err != nil { - logger.Errorf("error parsing validator index: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + if err != nil || index > math.MaxInt32 { // index in postgres is limited to int + logger.Warnf("error parsing validator index: %v", err) + http.Error(w, "Error: Invalid parameter validator index.", http.StatusBadRequest) return } @@ -1147,14 +1148,14 @@ func ValidatorWithdrawals(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } @@ -1224,9 +1225,9 @@ func ValidatorSlashings(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) index, err := strconv.ParseUint(vars["index"], 10, 64) - if err != nil { - logger.Errorf("error parsing validator index: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + if err != nil || index > math.MaxInt32 { // index in postgres is limited to int + logger.Warnf("error parsing validator index: %v", err) + http.Error(w, "Error: Invalid parameter validator index.", http.StatusBadRequest) return } @@ -1234,8 +1235,8 @@ func ValidatorSlashings(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } @@ -1383,7 +1384,7 @@ func ValidatorSave(w http.ResponseWriter, r *http.Request) { pubkeyDecoded, err := hex.DecodeString(pubkey) if err != nil { - logger.Errorf("error parsing submitted pubkey %v: %v", pubkey, err) + logger.Warnf("error parsing submitted pubkey %v: %v", pubkey, err) utils.SetFlash(w, r, validatorEditFlash, "Error: the provided signature is invalid") http.Redirect(w, r, "/validator/"+pubkey, http.StatusMovedPermanently) return @@ -1496,9 +1497,9 @@ func ValidatorHistory(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) index, err := strconv.ParseUint(vars["index"], 10, 64) - if err != nil { - logger.Errorf("error parsing validator index: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + if err != nil || index > math.MaxInt32 { // index in postgres is limited to int + logger.Warnf("error parsing validator index: %v", err) + http.Error(w, "Error: Invalid parameter validator index.", http.StatusBadRequest) return } @@ -1506,15 +1507,15 @@ func ValidatorHistory(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } @@ -1763,8 +1764,8 @@ func ValidatorStatsTable(w http.ResponseWriter, r *http.Request) { // Request came with a validator index number index, err = strconv.ParseUint(vars["index"], 10, 64) // Request is not a valid index number - if err != nil { - logger.Errorf("error parsing validator index: %v", err) + if err != nil || index > math.MaxInt32 { // index in postgres is limited to int + logger.Warnf("error parsing validator index: %v", err) validatorNotFound(data, w, r, vars, "/stats") return } @@ -1828,9 +1829,9 @@ func ValidatorSync(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) validatorIndex, err := strconv.ParseUint(vars["index"], 10, 64) - if err != nil { - logger.Errorf("error parsing validator index: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + if err != nil || validatorIndex > math.MaxInt32 { // index in postgres is limited to int + logger.Warnf("error parsing validator index: %v", err) + http.Error(w, "Error: Invalid parameter validator index.", http.StatusBadRequest) return } diff --git a/handlers/validatorRewards.go b/handlers/validatorRewards.go index 2b062407b7..8e6c58748a 100644 --- a/handlers/validatorRewards.go +++ b/handlers/validatorRewards.go @@ -116,20 +116,24 @@ func RewardsHistoricalData(w http.ResponseWriter, r *http.Request) { currency := q.Get("currency") - var start uint64 = 0 - var end uint64 = 0 + // Set the default start and end time to the first day + t := time.Unix(int64(utils.Config.Chain.GenesisTimestamp), 0) + startGenesisDay := uint64(time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.UTC).Unix()) + var start uint64 = startGenesisDay + var end uint64 = startGenesisDay + dateRange := strings.Split(q.Get("days"), "-") if len(dateRange) == 2 { - start, err = strconv.ParseUint(dateRange[0], 10, 64) - if err != nil { - logger.Errorf("error retrieving days range %v", err) - http.Error(w, "Invalid query", 400) + start, err = strconv.ParseUint(dateRange[0], 10, 32) //Limit to uint32 for postgres + if err != nil || start < startGenesisDay { + logger.Warnf("error parsing days range: %v", err) + http.Error(w, "Error: Invalid parameter days.", http.StatusBadRequest) return } - end, err = strconv.ParseUint(dateRange[1], 10, 64) - if err != nil { - logger.Errorf("error retrieving days range %v", err) - http.Error(w, "Invalid query", 400) + end, err = strconv.ParseUint(dateRange[1], 10, 32) //Limit to uint32 for postgres + if err != nil || end < startGenesisDay { + logger.Warnf("error parsing days range: %v", err) + http.Error(w, "Error: Invalid parameter days.", http.StatusBadRequest) return } } @@ -155,20 +159,24 @@ func DownloadRewardsHistoricalData(w http.ResponseWriter, r *http.Request) { currency := q.Get("currency") - var start uint64 = 0 - var end uint64 = 0 + // Set the default start and end time to the first day + t := time.Unix(int64(utils.Config.Chain.GenesisTimestamp), 0) + startGenesisDay := uint64(time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.UTC).Unix()) + var start uint64 = startGenesisDay + var end uint64 = startGenesisDay + dateRange := strings.Split(q.Get("days"), "-") if len(dateRange) == 2 { - start, err = strconv.ParseUint(dateRange[0], 10, 64) - if err != nil { - logger.Errorf("error retrieving days range %v", err) - http.Error(w, "Invalid query", 400) + start, err = strconv.ParseUint(dateRange[0], 10, 32) //Limit to uint32 for postgres + if err != nil || start < startGenesisDay { + logger.Warnf("error parsing days range: %v", err) + http.Error(w, "Error: Invalid parameter days.", http.StatusBadRequest) return } - end, err = strconv.ParseUint(dateRange[1], 10, 64) - if err != nil { - logger.Errorf("error retrieving days range %v", err) - http.Error(w, "Invalid query", 400) + end, err = strconv.ParseUint(dateRange[1], 10, 32) //Limit to uint32 for postgres + if err != nil || end < startGenesisDay { + logger.Warnf("error parsing days range: %v", err) + http.Error(w, "Error: Invalid parameter days.", http.StatusBadRequest) return } } diff --git a/handlers/validators.go b/handlers/validators.go index 9b2986641d..395b063b31 100644 --- a/handlers/validators.go +++ b/handlers/validators.go @@ -183,13 +183,13 @@ func parseValidatorsDataQueryParams(r *http.Request) (*ValidatorsDataQueryParams draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) return nil, err } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) return nil, err } if start > 10000 { @@ -199,7 +199,7 @@ func parseValidatorsDataQueryParams(r *http.Request) (*ValidatorsDataQueryParams length, err := strconv.ParseInt(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) return nil, err } if length < 0 { @@ -233,8 +233,8 @@ func ValidatorsData(w http.ResponseWriter, r *http.Request) { dataQuery, err := parseValidatorsDataQueryParams(r) if err != nil { - logger.Errorf("error parsing query-data: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error parsing query-data: %v", err) + http.Error(w, "Error: Invalid query-data parameter.", http.StatusBadRequest) return } diff --git a/handlers/validators_leaderboard.go b/handlers/validators_leaderboard.go index 64dcbc9b1a..eccc2a6fd1 100644 --- a/handlers/validators_leaderboard.go +++ b/handlers/validators_leaderboard.go @@ -56,20 +56,20 @@ func ValidatorsLeaderboardData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { diff --git a/handlers/validators_slashings.go b/handlers/validators_slashings.go index ca152a572f..09a115d388 100644 --- a/handlers/validators_slashings.go +++ b/handlers/validators_slashings.go @@ -34,21 +34,21 @@ func ValidatorsSlashingsData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { diff --git a/handlers/vis.go b/handlers/vis.go index 7252c193f2..4393256155 100644 --- a/handlers/vis.go +++ b/handlers/vis.go @@ -7,6 +7,7 @@ import ( "eth2-exporter/types" "eth2-exporter/utils" "fmt" + "math" "net/http" "strconv" "time" @@ -41,6 +42,13 @@ func VisBlocks(w http.ResponseWriter, r *http.Request) { sinceSlot := utils.TimeToSlot(uint64(since - 120)) + // slot in postgres is limited to int + if sinceSlot > math.MaxInt32 { + logger.Warnf("error retrieving block tree data, slot too big: %v", err) + http.Error(w, "Error: Invalid parameter since.", http.StatusBadRequest) + return + } + var chartData []*types.VisChartData err = db.ReaderDb.Select(&chartData, "select slot, blockroot, parentroot, proposer from blocks where slot >= $1 and status in ('1', '2') order by slot desc limit 50;", sinceSlot) diff --git a/handlers/withdrawals.go b/handlers/withdrawals.go index 267f134509..7839335ea0 100644 --- a/handlers/withdrawals.go +++ b/handlers/withdrawals.go @@ -59,15 +59,15 @@ func WithdrawalsData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } if start > db.WithdrawalsQueryLimit { @@ -75,8 +75,8 @@ func WithdrawalsData(w http.ResponseWriter, r *http.Request) { } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { @@ -234,14 +234,14 @@ func BLSChangeData(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } if start > db.BlsChangeQueryLimit { @@ -250,8 +250,8 @@ func BLSChangeData(w http.ResponseWriter, r *http.Request) { } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusServiceUnavailable) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { diff --git a/services/rewards.go b/services/rewards.go index caa79fe69b..ba4f153965 100644 --- a/services/rewards.go +++ b/services/rewards.go @@ -28,9 +28,9 @@ func GetValidatorHist(validatorArr []uint64, currency string, start uint64, end var pricesDb []types.Price // we get prices with a 1 day buffer to so we have no problems in different time zones - var oneDay = 24 * 60 * 60 + var oneDay = uint64(24 * 60 * 60) err = db.WriterDb.Select(&pricesDb, - `select ts, eur, usd, gbp, cad, jpy, cny, rub, aud from price where ts >= TO_TIMESTAMP($1) and ts <= TO_TIMESTAMP($2) order by ts desc`, start-uint64(oneDay), end+uint64(oneDay)) + `select ts, eur, usd, gbp, cad, jpy, cny, rub, aud from price where ts >= TO_TIMESTAMP($1) and ts <= TO_TIMESTAMP($2) order by ts desc`, start-oneDay, end+oneDay) if err != nil { logger.Errorf("error getting prices: %v", err) } diff --git a/utils/utils.go b/utils/utils.go index 7f1d072982..f8e2ce2fa9 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -249,9 +249,9 @@ func IncludeHTML(path string) template.HTML { return template.HTML(string(b)) } -func GraffitiToSring(graffiti []byte) string { +func GraffitiToString(graffiti []byte) string { s := strings.Map(fixUtf, string(bytes.Trim(graffiti, "\x00"))) - s = strings.Replace(s, "\u0000", "", -1) // rempove 0x00 bytes as it is not supported in postgres + s = strings.Replace(s, "\u0000", "", -1) // remove 0x00 bytes as it is not supported in postgres if !utf8.ValidString(s) { return "INVALID_UTF8_STRING" @@ -265,6 +265,22 @@ func FormatGraffitiString(graffiti string) string { return strings.Map(fixUtf, template.HTMLEscapeString(graffiti)) } +func HasProblematicUtfCharacters(s string) bool { + // Check for null character ('\x00') + if utf8.ValidString(s) && utf8.Valid([]byte(s)) { + // Check for control characters ('\x01' to '\x1F' and '\x7F') + for _, r := range s { + if r <= 0x1F || r == 0x7F { + return true + } + } + } else { + return true // Invalid UTF-8 sequence + } + + return false +} + func fixUtf(r rune) rune { if r == utf8.RuneError { return -1 From e4dc88357bf9407394373ebc962cf8fbf91177c5 Mon Sep 17 00:00:00 2001 From: spletka Date: Wed, 6 Sep 2023 16:58:56 +0200 Subject: [PATCH 2/4] (BIDS-2417) Further wrong user input errors --- cmd/explorer/main.go | 2 +- handlers/dashboard.go | 4 +-- handlers/epoch.go | 3 ++- handlers/slot.go | 47 +++++++++++++++++---------------- handlers/user.go | 14 +++++----- handlers/validator.go | 24 ++++++++--------- templates/validator/modals.html | 2 +- utils/utils.go | 6 +++++ 8 files changed, 54 insertions(+), 48 deletions(-) diff --git a/cmd/explorer/main.go b/cmd/explorer/main.go index 8518634075..f393a5edd4 100644 --- a/cmd/explorer/main.go +++ b/cmd/explorer/main.go @@ -467,7 +467,7 @@ func main() { router.HandleFunc("/validator/{pubkey}/deposits", handlers.ValidatorDeposits).Methods("GET") router.HandleFunc("/validator/{index}/slashings", handlers.ValidatorSlashings).Methods("GET") router.HandleFunc("/validator/{index}/effectiveness", handlers.ValidatorAttestationInclusionEffectiveness).Methods("GET") - router.HandleFunc("/validator/{pubkey}/save", handlers.ValidatorSave).Methods("POST") + router.HandleFunc("/validator/save", handlers.ValidatorSave).Methods("POST") router.HandleFunc("/watchlist/add", handlers.UsersModalAddValidator).Methods("POST") router.HandleFunc("/validator/{pubkey}/remove", handlers.UserValidatorWatchlistRemove).Methods("POST") router.HandleFunc("/validator/{index}/stats", handlers.ValidatorStatsTable).Methods("GET") diff --git a/handlers/dashboard.go b/handlers/dashboard.go index 1575e49da5..db05d3b029 100644 --- a/handlers/dashboard.go +++ b/handlers/dashboard.go @@ -450,8 +450,8 @@ func DashboardDataBalanceCombined(w http.ResponseWriter, r *http.Request) { if len(param) != 0 { days, err := strconv.ParseUint(param, 10, 32) if err != nil { - logger.Error(err) - http.Error(w, "Error: invalid days parameter", http.StatusBadRequest) + logger.Warnf("error parsing days: %v", err) + http.Error(w, "Error: invalid parameter days", http.StatusBadRequest) return } lastStatsDay := services.LatestExportedStatisticDay() diff --git a/handlers/epoch.go b/handlers/epoch.go index 975402577c..7efea28c3e 100644 --- a/handlers/epoch.go +++ b/handlers/epoch.go @@ -9,6 +9,7 @@ import ( "eth2-exporter/types" "eth2-exporter/utils" "fmt" + "math" "net/http" "strconv" "strings" @@ -29,7 +30,7 @@ func Epoch(w http.ResponseWriter, r *http.Request) { var epochFutureTemplate = templates.GetTemplate(epochFutureTemplateFiles...) var epochNotFoundTemplate = templates.GetTemplate(epochNotFoundTemplateFiles...) - const MaxEpochValue = 4294967296 // we only render a page for epochs up to this value + const MaxEpochValue = math.MaxUint32 + 1 // we only render a page for epochs up to this value w.Header().Set("Content-Type", "text/html") vars := mux.Vars(r) diff --git a/handlers/slot.go b/handlers/slot.go index 39bc14d641..73023f072d 100644 --- a/handlers/slot.go +++ b/handlers/slot.go @@ -11,6 +11,7 @@ import ( "eth2-exporter/utils" "fmt" "html/template" + "math" "math/big" "net/http" "strconv" @@ -61,7 +62,7 @@ func Slot(w http.ResponseWriter, r *http.Request) { if err != nil || len(slotOrHash) != 64 { blockRootHash = []byte{} blockSlot, err = strconv.ParseInt(vars["slotOrHash"], 10, 64) - if err != nil || blockSlot >= 2147483648 { // block slot must be lower then max int4 + if err != nil || blockSlot > math.MaxInt32 { // block slot must be lower than max int4 data := InitPageData(w, r, "blockchain", "/slots", fmt.Sprintf("Slot %v", slotOrHash), blockNotFoundTemplateFiles) data.Data = "slot" if handleTemplateError(w, r, "slot.go", "Slot", "blockSlot", blockNotFoundTemplate.ExecuteTemplate(w, "layout", data)) != nil { @@ -430,8 +431,8 @@ func SlotDepositData(w http.ResponseWriter, r *http.Request) { if err != nil || len(slotOrHash) != 64 { blockSlot, err = strconv.ParseInt(vars["slotOrHash"], 10, 64) if err != nil { - logger.Errorf("error parsing slotOrHash url parameter %v, err: %v", vars["slotOrHash"], err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error parsing slotOrHash url parameter %v, err: %v", vars["slotOrHash"], err) + http.Error(w, "Error: Invalid parameter slotOrHash.", http.StatusBadRequest) return } } else { @@ -552,8 +553,8 @@ func SlotVoteData(w http.ResponseWriter, r *http.Request) { if err != nil || len(slotOrHash) != 64 { blockSlot, err = strconv.ParseInt(vars["slotOrHash"], 10, 64) if err != nil { - logger.Errorf("error parsing slotOrHash url parameter %v, err: %v", vars["slotOrHash"], err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error parsing slotOrHash url parameter %v, err: %v", vars["slotOrHash"], err) + http.Error(w, "Error: Invalid parameter slotOrHash.", http.StatusBadRequest) return } err = db.ReaderDb.Get(&blockRootHash, "select blocks.blockroot from blocks where blocks.slot = $1", blockSlot) @@ -574,10 +575,10 @@ func SlotVoteData(w http.ResponseWriter, r *http.Request) { q := r.URL.Query() search := q.Get("search[value]") - searchIsUint64 := false - searchUint64, err := strconv.ParseUint(search, 10, 64) - if err == nil { - searchIsUint64 = true + searchIsInt32 := false + searchInt32, err := strconv.ParseInt(search, 10, 32) + if err == nil && searchInt32 >= 0 { + searchIsInt32 = true } draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) @@ -635,8 +636,8 @@ func SlotVoteData(w http.ResponseWriter, r *http.Request) { http.Error(w, "Internal server error", http.StatusInternalServerError) return } - } else if searchIsUint64 { - err = db.ReaderDb.Get(&count, `SELECT count(*) FROM blocks_attestations WHERE beaconblockroot = $1 AND $2 = ANY(validators)`, blockRootHash, searchUint64) + } else if searchIsInt32 { + err = db.ReaderDb.Get(&count, `SELECT count(*) FROM blocks_attestations WHERE beaconblockroot = $1 AND $2 = ANY(validators)`, blockRootHash, searchInt32) if err != nil { logger.Errorf("error retrieving deposit count for slot %v", err) http.Error(w, "Internal server error", http.StatusInternalServerError) @@ -653,7 +654,7 @@ func SlotVoteData(w http.ResponseWriter, r *http.Request) { ORDER BY committeeindex LIMIT $3 OFFSET $4`, - blockRootHash, searchUint64, length, start) + blockRootHash, searchInt32, length, start) if err != nil { logger.Errorf("error retrieving block vote data: %v", err) http.Error(w, "Internal server error", http.StatusInternalServerError) @@ -709,8 +710,8 @@ func BlockTransactionsData(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) slot, err := strconv.ParseUint(vars["block"], 10, 64) if err != nil { - logger.Errorf("error parsing slot url parameter %v, err: %v", vars["slot"], err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error parsing slot url parameter %v: %v", vars["slot"], err) + http.Error(w, "Error: Invalid parameter slot.", http.StatusBadRequest) return } @@ -766,9 +767,9 @@ func SlotAttestationsData(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) slot, err := strconv.ParseUint(vars["slot"], 10, 64) - if err != nil { - logger.Errorf("error parsing slot url parameter %v, err: %v", vars["slot"], err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + if err != nil || slot > math.MaxInt32 { + logger.Warnf("error parsing slot url parameter %v: %v", vars["slot"], err) + http.Error(w, "Error: Invalid parameter slot.", http.StatusBadRequest) return } @@ -813,9 +814,9 @@ func SlotWithdrawalData(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) slot, err := strconv.ParseUint(vars["slot"], 10, 64) - if err != nil { - logger.Errorf("error parsing slot url parameter %v, err: %v", vars["slot"], err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + if err != nil || slot > math.MaxInt32 { + logger.Warnf("error parsing slot url parameter %v: %v", vars["slot"], err) + http.Error(w, "Error: Invalid parameter slot.", http.StatusBadRequest) return } withdrawals, err := db.GetSlotWithdrawals(slot) @@ -854,9 +855,9 @@ func SlotBlsChangeData(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) slot, err := strconv.ParseUint(vars["slot"], 10, 64) - if err != nil { - logger.Errorf("error parsing slot url parameter %v, err: %v", vars["slot"], err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + if err != nil || slot > math.MaxInt32 { + logger.Warnf("error parsing slot url parameter %v: %v", vars["slot"], err) + http.Error(w, "Error: Invalid parameter slot.", http.StatusBadRequest) return } blsChange, err := db.GetSlotBLSChange(slot) diff --git a/handlers/user.go b/handlers/user.go index b469c847e1..80b4b75ac7 100644 --- a/handlers/user.go +++ b/handlers/user.go @@ -2186,8 +2186,8 @@ func UserNotificationsUnsubscribeByHash(w http.ResponseWriter, r *http.Request) hashes, ok := q["hash"] if !ok { - logger.Errorf("no query params given") - http.Error(w, "invalid request", 400) + logger.Warn("error no query params given") + http.Error(w, "Error: Missing parameter hash.", http.StatusBadRequest) return } @@ -2195,7 +2195,7 @@ func UserNotificationsUnsubscribeByHash(w http.ResponseWriter, r *http.Request) if err != nil { // return fmt.Errorf("error beginning transaction") logger.WithError(err).Errorf("error committing transacton") - http.Error(w, "error processing request", 500) + http.Error(w, "error processing request", http.StatusInternalServerError) return } defer tx.Rollback() @@ -2204,8 +2204,8 @@ func UserNotificationsUnsubscribeByHash(w http.ResponseWriter, r *http.Request) for _, hash := range hashes { hash = strings.Replace(hash, "0x", "", -1) if !utils.HashLikeRegex.MatchString(hash) { - logger.Errorf("error validating unsubscribe digest hashes") - http.Error(w, "error processing request", 500) + logger.Warn("error validating unsubscribe digest hashes") + http.Error(w, "Error: Invalid parameter hash entry.", http.StatusBadRequest) } b, _ := hex.DecodeString(hash) bHashes = append(bHashes, b) @@ -2214,14 +2214,14 @@ func UserNotificationsUnsubscribeByHash(w http.ResponseWriter, r *http.Request) _, err = tx.ExecContext(ctx, `DELETE from users_subscriptions where unsubscribe_hash = ANY($1)`, pq.ByteaArray(bHashes)) if err != nil { logger.Errorf("error deleting from users_subscriptions %v", err) - http.Error(w, "error processing request", 500) + http.Error(w, "error processing request", http.StatusInternalServerError) return } err = tx.Commit() if err != nil { logger.WithError(err).Errorf("error committing transacton") - http.Error(w, "error processing request", 500) + http.Error(w, "error processing request", http.StatusInternalServerError) return } diff --git a/handlers/validator.go b/handlers/validator.go index 6f04731e0d..ab8744cfca 100644 --- a/handlers/validator.go +++ b/handlers/validator.go @@ -849,8 +849,8 @@ func ValidatorDeposits(w http.ResponseWriter, r *http.Request) { pubkey, err := hex.DecodeString(strings.Replace(vars["pubkey"], "0x", "", -1)) if err != nil { - logger.Errorf("error parsing validator public key %v: %v", vars["pubkey"], err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error parsing validator public key %v: %v", vars["pubkey"], err) + http.Error(w, "Error: Invalid parameter public key.", http.StatusBadRequest) return } @@ -1745,18 +1745,16 @@ func ValidatorStatsTable(w http.ResponseWriter, r *http.Request) { data := InitPageData(w, r, "validators", "/validators", "", templateFiles) // Request came with a hash - if strings.Contains(vars["index"], "0x") || len(vars["index"]) == 96 { - pubKey, err := hex.DecodeString(strings.Replace(vars["index"], "0x", "", -1)) + if utils.IsHash(vars["index"]) { + pubKey, err := hex.DecodeString(strings.TrimPrefix(vars["index"], "0x")) if err != nil { logger.Errorf("error parsing validator public key %v: %v", vars["index"], err) - validatorNotFound(data, w, r, vars, "/stats") - return } index, err = db.GetValidatorIndex(pubKey) if err != nil { - logger.Errorf("error parsing validator pubkey: %v", err) + logger.Warnf("error parsing validator pubkey: %v", err) validatorNotFound(data, w, r, vars, "/stats") return } @@ -1839,20 +1837,20 @@ func ValidatorSync(w http.ResponseWriter, r *http.Request) { draw, err := strconv.ParseUint(q.Get("draw"), 10, 64) if err != nil { - logger.Errorf("error converting datatables data draw-parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables draw parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter draw", http.StatusBadRequest) return } start, err := strconv.ParseUint(q.Get("start"), 10, 64) if err != nil { - logger.Errorf("error converting datatables start start-parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables start parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter start", http.StatusBadRequest) return } length, err := strconv.ParseUint(q.Get("length"), 10, 64) if err != nil { - logger.Errorf("error converting datatables length length-parameter from string to int: %v", err) - http.Error(w, "Internal server error", http.StatusInternalServerError) + logger.Warnf("error converting datatables length parameter from string to int: %v", err) + http.Error(w, "Error: Missing or invalid parameter length", http.StatusBadRequest) return } if length > 100 { diff --git a/templates/validator/modals.html b/templates/validator/modals.html index 6e2358e5ad..340552acfb 100644 --- a/templates/validator/modals.html +++ b/templates/validator/modals.html @@ -50,7 +50,7 @@ {{ define "validatorEditModal" }}