0

0

如何在Golang中防止SQL注入漏洞 Go语言预编译语句Prepare使用

P粉602998670

P粉602998670

发布时间:2026-03-14 16:52:31

|

844人浏览过

|

来源于php中文网

原创

db.Query 直接拼接字符串会导致SQL注入,因database/sql不解析SQL而原样发送;必须用db.Prepare+参数化查询,禁用MySQL客户端插值,表名/字段名等需白名单校验。

如何在golang中防止sql注入漏洞 go语言预编译语句prepare使用

为什么 db.Query 直接拼接字符串会出事

因为 Go 的 database/sql 包本身不解析 SQL,只是把字符串原样发给数据库。你写 "SELECT * FROM users WHERE name = '" + name + "'",攻击者传入 name = "admin' -- ",最终执行的就是 SELECT * FROM users WHERE name = 'admin' -- '——注释掉后续校验逻辑,直接越权。

这不是 Go 特有漏洞,但 Go 默认不拦截这种拼接,开发者容易误以为“没用 ORM 就安全”。

  • 所有用户输入(http.Request.FormValuejson.Unmarshal 解析的字段、URL 参数)都算不可信输入
  • fmt.Sprintfstrings.Replace+ 拼接 SQL 字符串,一律禁止
  • 即使加了单引号、转义引号(strings.Replace(name, "'", "''", -1)),也防不住 Unicode 绕过或数据库特定行为

必须用 db.Prepare + stmt.Exec/stmt.Query

预编译语句把 SQL 结构和参数分离:数据库先解析语法、生成执行计划,再把参数按类型绑定进占位符。参数永远不会被当 SQL 解析,天然免疫注入。

注意:不是所有 Prepare 调用都生效——有些驱动(如 sqlite3)在连接池里复用 stmt,而 mysql 驱动默认开启 interpolateParams=true 时可能退化为客户端拼接(需关掉)。

立即学习go语言免费学习笔记(深入)”;

  • MySQL 驱动要显式禁用客户端插值:db, _ := sql.Open("mysql", "user:pass@/dbname?interpolateParams=false")
  • PostgreSQL 驱动(lib/pq)只支持 $1, $2 占位符,不支持 ?
  • SQLite3 驱动支持 ?$1,但 Prepare 后必须调用 Close() 或让 defer stmt.Close() 管理生命周期,否则连接池可能卡住

示例正确写法:

BiLin AI
BiLin AI

免费的多语言AI搜索引擎

下载
stmt, err := db.Prepare("SELECT id, name FROM users WHERE age > ? AND status = ?")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close()
rows, err := stmt.Query(18, "active") // 参数类型自动匹配,不拼字符串

哪些地方容易漏掉预编译

最常翻车的是动态字段名、表名、ORDER BY 子句——这些不能用 ? 占位,因为预编译只允许参数化值,不允许参数化标识符。

比如 SELECT * FROM ?ORDER BY ? 会直接 panic 报错 sql: expected 0 arguments, got 1

  • 表名/字段名必须白名单校验:if !isValidTableName(table) { return errors.New("invalid table") }
  • 排序字段限定为几个固定值:switch sortField { case "created_at", "name", "score": ... }
  • IN 子句参数个数不确定?不能写 WHERE id IN (?),得动态生成 WHERE id IN (?, ?, ?)stmt.Query(ids...)

性能与连接池的隐含代价

Prepare 不是免费的——它会在数据库端创建执行计划并缓存,同时在 Go 连接池里维护 stmt 对象。高频短连接场景(如 Lambda 函数)可能比直接 Query 更慢,因为每次都要重 Prepare。

但绝大多数 Web 服务用长连接,Prepare 复用率高,反而更快(省去语法解析+优化步骤)。

  • 别在 handler 里每次请求都 db.Prepare,应提前在 init() 或启动时准备好,复用 stmt
  • 如果业务需要大量不同 SQL(比如报表模块有 50+ 查询模板),考虑用 sync.Pool 管理 stmt,避免 GC 压力
  • MySQL 5.7+ 默认 prepared_stmt_cache_size=32,超限会踢出旧 stmt;若观察到 Com_prepare_sql 持续上升,说明缓存不够或 stmt 泄漏

真正难的从来不是写对一行 stmt.Query,而是想清楚哪部分必须静态、哪部分能参数化、以及谁来为那几个不能参数化的字符串兜底校验。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

211

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

247

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

356

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

409

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

201

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1499

2025.06.17

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 6.2万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号