高级主题
安全
登录后可跨设备保存划线和私人笔记登录
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)
db.Table("users; drop table users;").Find(&users)
db.Delete(&User{}, "id=1; drop table users;")
db.Joins("inner join orders; drop table users;").Find(&users)
db.InnerJoins("inner join orders; drop table users;").Find(&users)
db.Exec("UPDATE users SET name = '?' WHERE id = 1", gorm.Expr("alice'; drop table users;-- "))
db.Where("id=1").Not("name = 'alice'; drop table users;").Find(&users)
db.Where("id=1").Or("name = 'alice'; drop table users;").Find(&users)
db.Find(&User{}, "name = 'alice'; drop table users;")
db.First(&users, "2 or 1=1-- ")
db.FirstOrCreate(&users, "2 or 1=1-- ")
db.FirstOrInit(&users, "2 or 1=1-- ")
db.Last(&users, "2 or 1=1-- ")
db.Take(&users, "2 or 1=1-- ")避免 SQL 注入的通用原则是不要信任用户提交的数据,可通过白名单验证测试用户输入是否符合已知、合法、预定义的输入范围,且使用用户输入时仅将其作为参数传递。
评论
登录后参与评论
正在加载评论…
KnowForge