Golang安全开发实践 防止SQL注入与XSS攻击

落芳同学_9975

落芳同学_9975

2026-06-10

705人浏览

原创

参数化查询占位符必须匹配驱动:MySQL用?,PostgreSQL用$1,写错会导致参数被当字面量处理或报错;动态标识符需白名单校验,ORM原生SQL仍须参数化。

golang安全开发实践 防止sql注入与xss攻击

用 database/sql 做参数化查询时,占位符写错会直接失效

Go 的 database/sql 本身不解析 SQL,占位符语义由驱动决定。MySQL 驱动用 ?,PostgreSQL 驱动用 $1、$2,SQLite 两者都支持但行为不一致。写错占位符不会报错,而是把参数当字面量传入,等价于字符串拼接。

  • MySQL 场景下写 $1 → 查询永远无结果,或意外匹配到字面值 $1 的记录
  • PostgreSQL 场景下写 ? → 驱动报错 sql: expected 0 arguments, got 1 或静默忽略参数
  • 跨数据库迁移时,硬编码占位符会导致运行时行为突变,建议封装统一的 QueryBuilder 抽象层,或直接用 GORM 这类屏蔽差异的 ORM

别在 GORM 里用 Raw() 或 Session().Exec() 拼接用户输入

GORM 默认安全,但它的原生 SQL 接口是“逃生舱口”——一旦打开,所有防护自动失效。常见错误是以为加了 Where() 就安全,结果在 Raw() 里又把变量塞进 SQL 字符串。

  • ❌ 错误: db.Raw("SELECT * FROM users WHERE name = '" + name + "'").Find(&users)
  • ✅ 正确: db.Where("name = ?", name).Find(&users) 或 db.Raw("SELECT * FROM users WHERE name = ?", name).Find(&users)
  • 动态表名/字段名无法参数化,必须白名单校验:比如只允许 name、email、created_at 出现在 ORDER BY 子句中
  • 用 gosec 扫描时,规则 G201 会标记所有 Raw() 调用,需人工确认是否带参数化

html/template 不等于万能盾,富文本和 JS 上下文要额外处理

html/template 只对 HTML 内容做转义,且只在模板渲染阶段生效。如果用户输入被拼进 JavaScript 字符串、CSS 属性、URL 参数或 innerHTML,它完全不起作用。

Golang Uber Dig
Golang Uber Dig

使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等

下载
  • ❌ 危险: <script>var name = "{{.UserName}}";</script> —— 当 UserName 是 "); alert(1); // 时,JS 执行逃逸
  • ✅ 安全做法:用 js.Marshal 编码后插入:<script>var name = {{.UserNameJSON}};</script>,其中 UserNameJSON 是 json.Marshal 后的字符串
  • 富文本必须净化,不能靠 template.HTML 放行:用 bluemonday 白名单策略,禁用 script、onerror、javascript: 等一切执行向量
  • HTTP 响应头仍需设置:Content-Security-Policy: default-src 'self' 是最后一道防线,防止 inline script 执行

输入验证不能替代输出编码,类型检查只是辅助手段

很多人以为 strconv.Atoi 转整数就防住了 SQL 注入,这是错觉。攻击者可以绕过类型检查,比如在 UUID 字段传入 1' OR '1'='1(字符串合法),或利用 JSON API 传嵌套结构触发未覆盖的解析路径。

  • 输入验证目标是“快速拒绝明显非法输入”,不是“构造安全边界”
  • ID 类型检查后仍要走 WHERE id = ?,不能拼成 "WHERE id = " + idStr
  • 邮箱、手机号等格式校验建议用正则+长度限制,但不要过度设计:比如邮箱正则太复杂反而导致 DoS(回溯爆炸)
  • 真正关键的是:所有输出到外部系统(SQL、HTML、JS、HTTP 头)的地方,都必须按目标上下文做对应编码,不能复用同一套“清洗逻辑”

最易被忽略的一点:安全不是单点开关。一个请求可能同时经过 SQL 查询、HTML 渲染、JS 初始化、CSP 头设置四个环节,任一环节漏掉上下文适配,整条链路就失效。写代码时得时刻问自己:这串数据接下来要去哪?谁会解释它?

golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

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

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

2024.02.23

539

5

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

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

2024.02.23

616

5

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

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

2024.02.23

1276

5

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

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

2024.03.05

791

5

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

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

2024.05.21

1866

6

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

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

2025.06.09

5334

18

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

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

2025.06.10

2474

13

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

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

2025.06.17

4326

17

golang数组大全
golang数组大全

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

2025.06.20

5586

22

热门下载

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

精品课程

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