安全

GORM 使用 database/sql 的参数占位符来构建 SQL 语句,这将自动转义参数以避免 SQL 注入

注意 Logger 中的 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 注入的一般规则是不信任用户提交的数据,您可以执行白名单验证以根据一组已知的、批准的和定义的输入来测试用户输入,并且在使用用户输入时,仅将它们用作参数。

铂金赞助商

黄金赞助商

铂金赞助商

黄金赞助商