安全性

GORM 使用 database/sql 的引數佔位符來建構 SQL 陳述式,這會自動跳脫引數以避免 SQL 注入

注意 記錄器的 SQL 沒有像執行的那樣完全跳脫,在 SQL 主控台中複製並執行時請小心

查詢條件

使用者的輸入應該只用作引數,例如

userInput := "jinzhu;drop table users;"

// safe, will be escaped
db.Where("name = ?", userInput).First(&user)

// SQL injection
db.Where(fmt.Sprintf("name = %v", userInput)).First(&user)

內嵌條件

// will be escaped
db.First(&user, "name = ?", userInput)

// SQL injection
db.First(&user, fmt.Sprintf("name = %v", userInput))

透過使用者的輸入,以數字主鍵擷取物件時,您應該檢查變數的類型。

userInputID := "1=1;drop table users;"
// safe, return error
id, err := strconv.Atoi(userInputID)
if err != nil {
return err
}
db.First(&user, id)

// SQL injection
db.First(&user, userInputID)
// SELECT * FROM users WHERE 1=1;drop table users;

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 注入的一般規則是不信任使用者提交的資料,您可以執行白名單驗證,以針對現有的一組已知、已核准和已定義的輸入,測試使用者的輸入,並且在使用使用者的輸入時,只將它們用作引數。

白金贊助商

金牌贊助商

白金贊助商

金牌贊助商