跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Go语言怎么防SQL注入_Go语言SQL注入防护教程【深入】

必须使用参数占位符(如?或$1)而非字符串拼接来防止SQL注入;sql.RawBytes仅用于读取二进制字段,不可用于拼接SQL;动态表名/字段名需白名单校验;ORM应禁用Raw()并启用PrepareStmt;JSON中的SQL片段同样需严格校验。 用
database/sql
的
Query
和
Exec
时必须带参数占位符 Go 原生
database/sql
包本身不拼接 SQL 字符串,但开发者一不小心就手写
fmt.Sprintf
或字符串拼接,直接把用户输入塞进查询里。这是最常见、最危险的入口。 正确做法永远是用
?
占位符(MySQL/SQLite)或
$1
(PostgreSQL),让驱动做参数绑定。数据库看到的不是“拼出来的字符串”,而是独立的值,根本不会当 SQL 解析。 错:
db.Query("SELECT * FROM users WHERE name = '" + name + "'")
—— 输入
' OR 1=1 --
就完蛋 对:
db.Query("SELECT * FROM users WHERE name = ?", name)
—— 驱动自动转义并隔离 PostgreSQL 要用
$1
、
$2
:
db.Query("SELECT * FROM users WHERE id = $1 AND status = $2", id, status)
sql.RawBytes
不是用来绕过参数绑定的 有人以为
sql.RawBytes
是“原始数据容器”,能用来动态拼 SQL,其实它只是读取二进制字段(比如
BLOB
)时的临时缓冲区类型,跟防注入毫无关系。拿它拼接查询等于自废防御。 常见错误场景:从配置表读 SQL 模板,再用
sql.RawBytes
拼上用户 ID——这和直接字符串拼接没区别,只是换了个难懂的写法。 立即学习 “ go语言免费学习笔记(深入) ”; go语言参考手册 中文CHM版 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译 下载
sql.RawBytes
只该出现在
Scan
接收列值时,比如读
MEDIUMBLOB
任何需要“动态表名”“动态字段名”的需求,都不能靠参数绑定解决,得走白名单校验或重构设计 真要拼表名?先查一遍
INFORMATION_SCHEMA.TABLES
确认存在,再硬编码比对,别信任何用户输入 ORM(如 GORM)开启
PrepareStmt
并禁用原生 SQL 拼接 GORM 默认会 prepare 语句,但如果你调用
Session(&gorm.Session{PrepareStmt: false})
或手动用
Raw()
执行字符串,防护就失效了。尤其
Raw()
+
Scan()
组合,极易写出带拼接的“伪安全”代码。 默认开启
PrepareStmt
时,
db.Where("name = ?", name).Find(&u)
是安全的 但
db.Raw("SELECT * FROM " + tableName + " WHERE id = ?", id).Scan(&u)
—— 表名未校验,照样中招 禁用
Raw()
,改用
Table(tableName)
:
db.Table(tableName).Where("id = ?", id).Find(&u)
,前提是
tableName
来自枚举或配置项 JSON 字段里的 SQL 片段不是“免检区” 有些服务把查询条件存成 JSON(比如搜索过滤器),后端解析后拼成 SQL。这时候容易误以为“JSON 是数据,不是代码”,放松校验。但只要最终进了
db.Query
的字符串参数,就是注入温床。 解析 JSON 后得到的
map[string]interface{}
,不能直接
fmt.Sprintf
进 SQL 字段名(如
"user_name"
)必须映射到预设白名单:
validFields := map[string]bool{"name": true, "email": true}
操作符(
"gt"
,
"like"
)也要限制范围,避免注入
OR 1=1
类逻辑 数值类值可直接参数化,字符串类值必须走
LIKE ?
而非
LIKE '%"+v+"%'
真正麻烦的从来不是语法怎么写,而是哪一层该信任输入、哪一层必须掐死拼接——边界模糊的地方,往往就是漏洞藏身的位置。

相关文章