Golang Web开发中SQL注入如何防范_Golang安全开发实践
技术百科
P粉602998670
发布时间:2026-01-27
浏览: 次 Go语言防SQL注入的关键是禁用字符串拼接、强制参数化查询,对表名等标识符须白名单校验,ORM原生查询也需避免拼接。
Go 语言本身不会自动导致 SQL 注入,但用 fmt.Sprintf、strconv 拼接查询字符串,或直接把用户输入塞进 db.Query,就等于把门敞开。
用 database/sql 的参数化查询代替字符串拼接
Go 标准库的 database/sql 原生支持占位符(? 或 $1 等,取决于驱动),这是防注入最直接有效的手段。关键不是“用了预处理”,而是“没让用户输入参与 SQL 结构生成”。
常见错误写法:
// ❌ 危险:字符串拼接
username := r.URL.Query().Get("user")
rows, _ := db.Query("SELECT * FROM users WHERE name = '" + username + "'")正确做法:
// ✅ 安全:参数绑定
username := r.URL.Query().Get("user")
rows, _ := db.Query("SELECT * FROM users WHERE name = ?", username)- MySQL 驱动(
github.com/go-sql-driver/mysql)用? - PostgreSQL 驱动(
github.com/lib/pq)用$1,$2 - SQLite 驱动(
github.com/mattn/go-sqlite3)也支持?和命名参数(:name) - 不要试图自己转义引号或过滤单引号——绕过方式太多,且易漏
避免在查询中动态拼接表名、字段名或 ORDER BY 子句
参数化查询只适用于值(value),不适用于标识符(identifier):表名、列名、排序方向(ASC/DESC)无法用 ? 占位。这类场景必须白名单校验。
例如,允许前端指定排序字段:
// ❌ 错误:直接拼接
sortField := r.URL.Query().Get("sort")
rows, _ := db.Query("SELECT * FROM posts ORDER BY " + sortField + " DESC")应改为:
// ✅ 白名单控制
validSortFields := map[string]bool{"title": true, "created_at": true, "author_id": true}
sortField := r.URL.Query().Get("sort")
if !validSortFields[sortField] {
http.Error(w, "invalid sort field", http.StatusBadRequest)
return
}
rows, _ := db.Query("SELECT * FROM posts ORDER BY " + sortField + " DESC")- 永远不要信任用户输入来决定 SQL 结构部分
- 用
map[string]bool或switch列出所有合法值,拒绝其余一切 - ORDER BY 后的 ASC/DESC 同理,不能靠字符串替换或正则“过滤”
慎用 sql.Raw 和第三方 ORM 的原生查询接口
像 GORM 的 Raw()、Session().Exec(),或 sqlx 的 Queryx 带格式化字符串,都可能绕过参数化逻辑。只要里面出现 fmt.Sprintf 或 + 拼接,风险就回来了。
例如 GORM 中的典型误用:
// ❌ 危险:Raw 中拼接
name := r.FormValue("name")
db.Raw("SELECT * FROM users WHERE name = '" + name + "'").Scan(&users)应统一走参数化路径:
// ✅ 正确:Raw 支持问号占位
name := r.FormValue("name")
db.Raw("SELECT * FROM users WHERE name = ?", name).Scan(&users)- GORM v2+ 的
Whe方法默认安全(内部用参数绑定),优先用它
re()
- 如果必须用
Raw,确保所有用户输入都作为参数传入,而非拼进 SQL 字符串 - 注意某些 ORM 的“命名参数”语法(如
:name)仍需配合sql.Named或对应驱动支持,不能混用
真正难防的不是技术点,而是开发时那一秒的“我就拼一下,反正这个字段前端可控”。SQL 注入漏洞往往藏在日志查询、导出接口、管理后台的模糊搜索里——这些地方最容易被当成“低风险”而跳过参数化。只要用户输入进了 SQL 字符串字面量,就该立刻停下来检查。
# go语言
# go
# golang
# String
# git
# github
# 前端
# usb
# session
# switch
# mysql
# sql
# sql注入
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- c++中如何求一个数的平方根_c++ sqrt函数
- Win11开机自检怎么关闭_跳过Win11开机磁盘
- mac怎么安装adb_MAC配置Android A
- 当网站SEO排名下降时,如何应对?
- Windows10如何更改日期格式_Win10区域
- Python对象生命周期管理_创建销毁解析【教程】
- Mac怎么给文件夹加密_Mac创建加密磁盘映像教程
- 如何使用Golang构建基础消息队列模拟_Gola
- php嵌入式需要什么环境_搭建php+linux嵌
- 如何在同包不同文件中正确引用 Go 结构体
- Python文件和流处理指南_高效读写大体积数据文
- Win11怎么禁用键盘自带键盘_Win11笔记本禁
- Win11怎么设置虚拟内存最佳大小_Windows
- Win11如何设置电源计划_Win11电源计划优化
- Win11怎么关闭资讯和兴趣_Windows11任
- Windows怎样关闭桌面弹窗广告_Windows
- Win11资源管理器卡顿怎么办 Win11文件资源
- 如何使用Golang包导出规则_控制函数和变量可见
- php中::能访问全局变量吗_全局作用域与类作用域
- 零基础学会Python自动化办公_高效处理Exce
- Python项目维护经验_长期演进说明【指导】
- Win11怎么设置右键刷新选项_Windows11
- Win11怎么关闭自动调节亮度 Win11禁用内容
- c++如何使用std::bind绑定函数参数_c+
- Python文本编码与解码_跨平台解析说明【指导】
- 如何使用正则表达式批量替换重复的星号-短横模式为固
- phpstudy本地环境mysql忘记密码_重置m
- php485能和物联网模块通信吗_php485对接
- PowerShell怎么创建复杂的XML结构
- Python安全爬虫设计_IP代理池与验证码识别策
- Linux如何挂载新硬盘_Linux磁盘分区格式化
- php本地部署支持nodejs吗_php与node
- mac怎么右键_MAC鼠标右键设置与触控板手势技巧
- Win10如何备份驱动程序_Win10驱动备份步骤
- c++的STL算法库find怎么用 在容器中查找指
- 短链接还原php提示内存不足_调整PHP内存限制设
- Win11如何添加/删除输入法 Win11切换中英
- php订单日志怎么记录发货_php记录订单发货操作
- c++如何连接Redis c++ hiredis库
- 如何在Golang中指定模块版本_使用go.mod
- Win11怎么解压RAR文件 Win11自带解压功
- 如何使用正则表达式精确匹配最多含一个换行符的 st
- c++ atoi和atof函数用法_c++字符数组
- Win11怎么关闭系统声音_Win11系统提示音静
- 如何在 Go 项目开发中正确处理本地包导入与远程模
- 如何在 Windows 11 中使用 AlomWa
- Win11怎么清理C盘下载文件夹_Win11清理下
- Windows家庭版如何开启组策略(gpedit.
- windows如何测试网速_windows系统网络
- php本地部署后数据库连接报错_1045acces


QQ客服