database/sql防注入完全依赖正确使用占位符和标识符校验:mysql/sqlite用?、postgresql用$1等,混用会报错;表名、字段名、排序方向等必须白名单校验;prepare需配对close;scan需处理null和顺序匹配。

database/sql 本身不防注入,防注入靠的是你写 SQL 的方式——只要用对占位符、不拼字符串、不碰标识符,SQL 注入在 Go 里就是可完全规避的。
占位符必须匹配驱动,混用直接报错
MySQL/SQLite 驱动只认 ?,PostgreSQL 驱动只认 $1、$2。这不是风格选择,是协议级硬约束。
-
db.Query("SELECT * FROM users WHERE id = ? AND status = ?", id, "active")✅(MySQL) -
db.Query("SELECT * FROM users WHERE id = $1 AND status = $2", id, "active")✅(PostgreSQL) -
db.Query("SELECT * FROM users WHERE id = ? AND status = $1", id, "active")❌ 混用,驱动可能忽略第二个参数,或报sql: expected 0 arguments, got 1
别指望驱动自动转换占位符——它连语法校验都懒得做,错配后行为不可控,轻则查不到数据(sql: no rows in result set),重则触发数据库语法错误。
表名、字段名、ORDER BY 不能用 ? 绑定
SQL 标准不允许参数化标识符(identifier),database/sql 驱动也不支持。试图写 db.Query("SELECT * FROM ? WHERE name = ?", tableName, name) 会 panic 或静默失败。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
- 排序字段必须白名单校验:
validSortFields := map[string]bool{"created_at": true, "name": true, "score": true},再用if !validSortFields[sortField] { return errors.New("invalid sort field") } - 表名映射建议走常量或 switch:
switch input { case "prod": realTable = "users_prod"; case "test": realTable = "users_test" },而不是"users_" + input -
ASC/DESC同样要校验,不能靠参数传;IN子句也不能用IN (?),得手动拼IN (?, ?, ?)并传等长切片
Prepare 必须配对 Close,否则连接泄漏
*sql.Stmt 是有状态对象,内部持有连接资源。不 Close() 就等于把连接池里的“座位”一直占着。
- 高并发下易触发
sql: connection refused或长时间阻塞 - 必须写
defer stmt.Close(),尤其函数内多次调用时 - 别在循环里反复
Prepare同一语句——复用*sql.Stmt,它本身并发安全 - 如果只查一次,直接用
db.Query更省心,它内部会自动Prepare+Close
Scan 必须显式处理 NULL 和类型顺序
Scan 不参与防注入,但它出错会暴露结构、引发 panic,甚至间接导致逻辑异常。
- 字段可能为
NULL却用普通string接收 →panic: sql: Scan error on column index 0: unsupported Scan, storing driver.Value type <nil> into type *string</nil> - 所有可能为
NULL的字段,必须用sql.NullString、sql.NullInt64等类型接收 - 按 SELECT 列顺序硬匹配,别堆匿名变量;推荐具名变量:
err := row.Scan(&u.ID, &u.Name, &u.Email) - 结构体字段名必须和 SELECT 别名一致,比如
SELECT id, name AS username对应Username string
最易被忽略的点:占位符只保值,不保结构。表名、字段名、排序方向这些,数据库层根本不允许参数化——漏掉白名单校验,前面所有参数化都白做。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










