@@ -23,7 +23,7 @@ import (
2323 "net/http"
2424 "strings"
2525 "time"
26-
26+ "regexp"
2727 "github.com/gin-gonic/gin"
2828
2929 "github.com/karmada-io/dashboard/cmd/metrics-scraper/app/scrape"
@@ -74,6 +74,11 @@ func QueryMetrics(c *gin.Context) {
7474}
7575
7676func queryMetricNames (c * gin.Context , tx * sql.Tx , sanitizedPodName string ) {
77+ if ! isValidTableName (sanitizedPodName ) {
78+ log .Printf ("Invalid table name: %v" , sanitizedPodName )
79+ c .JSON (http .StatusBadRequest , gin.H {"error" : "Invalid table name" })
80+ return
81+ }
7782 rows , err := tx .Query (fmt .Sprintf ("SELECT DISTINCT name FROM %s" , sanitizedPodName ))
7883 if err != nil {
7984 log .Printf ("Error querying metric names: %v, SQL Error: %v" , err , err )
@@ -96,6 +101,14 @@ func queryMetricNames(c *gin.Context, tx *sql.Tx, sanitizedPodName string) {
96101 c .JSON (http .StatusOK , gin.H {"metricNames" : metricNames })
97102}
98103
104+ // isValidTableName checks if the given table name is a valid identifier.
105+ func isValidTableName (name string ) bool {
106+ // Only allow table names that start with a letter or underscore, then letters, numbers, underscores, up to 64 chars
107+ // Adjust length as per your table name limits (e.g., SQLite, MySQL usually 64)
108+ validTableName := regexp .MustCompile (`^[a-zA-Z_][a-zA-Z0-9_]{0,63}$` )
109+ return validTableName .MatchString (name )
110+ }
111+
99112func queryMetricDetailsByName (c * gin.Context , tx * sql.Tx , sanitizedPodName , metricName string ) {
100113 if metricName == "" {
101114 c .JSON (http .StatusBadRequest , gin.H {"error" : "Metric name required for details" })
0 commit comments