GORM 使用 database/sql
的引數佔位符來建構 SQL 陳述式,這會自動跳脫引數以避免 SQL 注入
注意 記錄器的 SQL 沒有像執行的那樣完全跳脫,在 SQL 主控台中複製並執行時請小心
查詢條件
使用者的輸入應該只用作引數,例如
userInput := "jinzhu;drop table users;"
db.Where("name = ?", userInput).First(&user)
db.Where(fmt.Sprintf("name = %v", userInput)).First(&user)
|
內嵌條件
db.First(&user, "name = ?", userInput)
db.First(&user, fmt.Sprintf("name = %v", userInput))
|
透過使用者的輸入,以數字主鍵擷取物件時,您應該檢查變數的類型。
userInputID := "1=1;drop table users;"
id, err := strconv.Atoi(userInputID) if err != nil { return err } db.First(&user, id)
db.First(&user, userInputID)
|
SQL 注入方法
為了支援一些功能,某些輸入不會跳脫,在使用這些方法時,請小心使用使用者的輸入
db.Select("name; drop table users;").First(&user) db.Distinct("name; drop table users;").First(&user)
db.Model(&user).Pluck("name; drop table users;", &names)
db.Group("name; drop table users;").First(&user)
db.Group("name").Having("1 = 1;drop table users;").First(&user)
db.Raw("select name from users; drop table users;").First(&user)
db.Exec("select name from users; drop table users;")
db.Order("name; drop table users;").First(&user)
|
避免 SQL 注入的一般規則是不信任使用者提交的資料,您可以執行白名單驗證,以針對現有的一組已知、已核准和已定義的輸入,測試使用者的輸入,並且在使用使用者的輸入時,只將它們用作引數。