From e4dc88357bf9407394373ebc962cf8fbf91177c5 Mon Sep 17 00:00:00 2001 From: spletka Date: Wed, 6 Sep 2023 16:58:56 +0200 Subject: [PATCH] (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" }}