gorm 不自动防 sql 注入,安全取决于用户输入是否作为参数而非 sql 结构拼接;where(string) 和 raw() 直接透传字符串极危险,必须用参数化绑定或白名单校验表名、字段名等结构部分。

直接说结论:GORM 不自动防 SQL 注入,安全与否完全取决于你是否把用户输入当“值”传参,还是当“结构”拼进 SQL 字符串里。
Where 方法只传一个字符串就是裸奔
GORM 的 Where 方法有两个重载签名:Where(string) 和 Where(string, interface{})。只有后者才启用参数化绑定;前者等同于把整个字符串当原生 SQL 片段透传。
- ❌
db.Where("name = '" + name + "'").First(&u):单引号被绕过,name是"admin' OR 1=1 --"就直接查出所有用户 - ✅
db.Where("name = ?", name).First(&u):name被驱动作为纯数据绑定,无论内容多危险都不会改变 SQL 结构 - ⚠️ 混合写法也崩盘:
db.Where("age > ?", age).Where("status = '" + status + "'")——后半段已失守
Raw() 不是快捷方式,是高危入口
Raw() 绕过 GORM 所有 ORM 层检查,直连底层 driver。它本身不危险,危险的是你塞进去的字符串里混了未校验的用户输入。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
- ❌
db.Raw("SELECT * FROM " + tableName + " WHERE id = ?", id):表名拼接即失守,tableName是"users; DROP TABLE admins --"就完了 - ✅ 正确路径分两步:
if !validTables[tableName] { return errors.New("invalid table") },再用db.Table(tableName).Where("id = ?", id).Scan(&u) - ✅ 若必须用
Raw()动态排序:if !validSortFields[field] || (dir != "ASC" && dir != "DESC") { return err },之后拼"ORDER BY " + field + " " + dir才算安全
IN 子句、空切片和类型匹配这些细节容易翻车
IN 看似简单,但处理不当会触发注入或 panic;Scan 不防注入,但字段顺序/类型错配会导致静默数据错乱甚至服务崩溃。
- ✅
db.Where("id IN ?", []uint{1, 2, 3}).Find(&users):GORM 自动展开为IN (1,2,3),安全且兼容空切片(空时生成IN (?)并跳过) - ❌
db.Raw("SELECT * FROM users WHERE id IN (" + idsStr + ")").Scan(&u):若idsStr来自用户且含"1, (SELECT password FROM admins)",就中招 - ✅ 接收可能为 NULL 的字段必须用
sql.NullString或*string,普通string遇到 NULL 会 panic - ✅ 显式写 SELECT 字段:
SELECT id, name, email FROM users,别用SELECT *;接收时优先用结构体,字段顺序与列严格对应
泛型 GORM 和 GEN 能从源头掐断部分风险
传统 *gorm.DB 是泛型擦除的,编译期无法捕获模型错用;而泛型版 gorm.G[User] 和代码生成工具 GEN 可在编译期拦截字段名拼错、表名误用等低级错误。
- ✅
gorm.G[User](db).Where("name = ?", name).First(ctx, &user):类型不匹配直接编译失败,不会运行时查错表 - ✅ GEN 把注释里的 SQL 模板(如
// select * from users where name = {{.name}})转成带校验的 Go 方法,字段名写错也会编译报错 - ⚠️ 泛型 API 要求 GORM >= v1.30.0;GEN 生成的 query 默认需传
context,漏传会 panic
最易被忽略的点始终是:表名、字段名、ORDER BY 方向这些“结构部分”,数据库根本不允许参数化,也没有所谓“安全占位符”。白名单校验必须在 SQL 构建前完成,且不能靠事后过滤或转义补救。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










