Skip to content

Commit ec93ab0

Browse files
committed
fix: ensure the list sort query is validated to prevent SQL injection
Credits to @jorgectf for the advisories.
1 parent 827e76c commit ec93ab0

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

api/cosy/sort.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,39 @@ package cosy
22

33
import (
44
"fmt"
5+
"github.com/0xJacky/Nginx-UI/internal/logger"
56
"github.com/gin-gonic/gin"
67
"gorm.io/gorm"
8+
"gorm.io/gorm/schema"
9+
"sync"
710
)
811

912
func (c *Ctx[T]) SortOrder() func(db *gorm.DB) *gorm.DB {
1013
return func(db *gorm.DB) *gorm.DB {
1114
sort := c.ctx.DefaultQuery("order", "desc")
12-
order := fmt.Sprintf("%s %s", DefaultQuery(c.ctx, "sort_by", c.itemKey), sort)
13-
return db.Order(order)
15+
if sort != "desc" && sort != "asc" {
16+
sort = "desc"
17+
}
18+
19+
// check if the order field is valid
20+
// todo: maybe we can use more generic way to check if the sort_by is valid
21+
order := DefaultQuery(c.ctx, "sort_by", c.itemKey)
22+
s, _ := schema.Parse(c.Model, &sync.Map{}, schema.NamingStrategy{})
23+
if _, ok := s.FieldsByDBName[order]; ok {
24+
order = fmt.Sprintf("%s %s", order, sort)
25+
return db.Order(order)
26+
} else {
27+
logger.Error("invalid order field:", order)
28+
}
29+
30+
return db
1431
}
1532
}
1633

1734
func (c *Ctx[T]) OrderAndPaginate() func(db *gorm.DB) *gorm.DB {
1835
return func(db *gorm.DB) *gorm.DB {
19-
sort := c.ctx.DefaultQuery("order", "desc")
20-
21-
order := fmt.Sprintf("%s %s", DefaultQuery(c.ctx, "sort_by", c.itemKey), sort)
22-
db = db.Order(order)
23-
36+
db = c.SortOrder()(db)
2437
_, offset, pageSize := GetPagingParams(c.ctx)
25-
2638
return db.Offset(offset).Limit(pageSize)
2739
}
2840
}

model/model.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import (
1010
"gorm.io/gen"
1111
"gorm.io/gorm"
1212
gormlogger "gorm.io/gorm/logger"
13+
"gorm.io/gorm/schema"
1314
"path"
1415
"strings"
16+
"sync"
1517
"time"
1618
)
1719

@@ -100,9 +102,19 @@ func SortOrder(c *gin.Context) func(db *gorm.DB) *gorm.DB {
100102
func OrderAndPaginate(c *gin.Context) func(db *gorm.DB) *gorm.DB {
101103
return func(db *gorm.DB) *gorm.DB {
102104
sort := c.DefaultQuery("order", "desc")
105+
if sort != "desc" && sort != "asc" {
106+
sort = "desc"
107+
}
103108

104-
order := fmt.Sprintf("`%s` %s", DefaultQuery(c, "sort_by", "id"), sort)
105-
db = db.Order(order)
109+
// check if the order field is valid
110+
order := c.DefaultQuery("sort_by", "id")
111+
s, _ := schema.Parse(db.Model, &sync.Map{}, schema.NamingStrategy{})
112+
if _, ok := s.FieldsByName[order]; ok {
113+
order = fmt.Sprintf("%s %s", order, sort)
114+
db = db.Order(order)
115+
} else {
116+
logger.Error("invalid order field: ", order)
117+
}
106118

107119
page := cast.ToInt(c.Query("page"))
108120
if page == 0 {

0 commit comments

Comments
 (0)