Apollo 技术文档Apollo 技术文档
指南
  • 架构概述
  • BigWorld 架构深度解析
  • BigWorld 进程架构与玩家生命周期
  • AOI九宫格系统详解
  • AOI广播与消息去重
  • Base 模块
  • Core 模块
  • Runtime 模块
  • Data 模块
  • Network 模块
  • /modules/actor.html
  • Game 模块
  • BigWorld 模块
服务器应用
API 参考
QA
GitHub
指南
  • 架构概述
  • BigWorld 架构深度解析
  • BigWorld 进程架构与玩家生命周期
  • AOI九宫格系统详解
  • AOI广播与消息去重
  • Base 模块
  • Core 模块
  • Runtime 模块
  • Data 模块
  • Network 模块
  • /modules/actor.html
  • Game 模块
  • BigWorld 模块
服务器应用
API 参考
QA
GitHub
  • MMORPG 架构 QA

Q88: 如何防止 SQL 注入?

核心结论

防 SQL 注入最核心的一条原则很简单:

  • SQL 结构和用户输入必须分离

也就是说,查询语句的结构由程序定义,外部输入只能作为参数,而不能拼进 SQL 结构里。

剩下的输入校验、ORM、权限控制,都是补充层。

一、SQL 注入真正的根因是什么

根因通常不是“用户输入脏”,而是程序把外部输入当成 SQL 语法的一部分拼接进去。

只要结构和数据混在一起,注入风险就一直存在。

二、参数化查询是主方案,不是建议项

无论使用:

  • 原生驱动
  • ORM
  • 查询构建器

核心都应该是参数绑定,而不是字符串拼接。

这不是风格问题,而是边界问题。

三、ORM 也不能自动保证安全

ORM 能减少手写 SQL,但不代表天然没有注入风险。

一旦出现:

  • 拼接原生 SQL
  • 动态表名或排序字段直拼
  • 拼接 where 条件片段

风险仍然存在。

所以真正要防的是“不受控拼接”,而不是只看是不是 ORM。

四、白名单校验对动态字段尤其重要

有些场景确实需要动态控制,例如:

  • 排序字段
  • 排序方向
  • 可选查询列

这些不能简单参数化的部分,通常应使用白名单映射,而不是把客户端输入原样拼进去。

五、权限和最小暴露面也很重要

即使有注入风险,如果数据库账号权限被严格限制,破坏面也会小很多。

更稳妥的做法通常是:

  • 应用账号最小权限
  • 读写账号分离
  • 后台高危库隔离

这样能降低事故影响范围。

六、日志和监控里也要注意注入面

很多系统只盯主查询路径,却忽略:

  • 报表查询
  • 后台搜索
  • 运维脚本
  • 临时 SQL 工具

这些地方往往更容易因为“临时方便”而回到字符串拼接。

七、工程上更稳妥的做法

常见做法是:

  • 所有查询默认参数化
  • 动态 SQL 的结构部分走白名单
  • 数据库账号最小权限
  • 高风险后台接口单独审查

八、常见误区

1. 用 ORM 就不会有 SQL 注入

不对。只要有原生拼接,风险仍然存在。

2. 只过滤特殊字符就够了

过滤只能辅助,不能替代参数化。

3. 只有登录接口才需要防注入

后台查询、报表、搜索和脚本同样是高风险点。

参考资料

  • 参数化查询、白名单动态 SQL 和最小权限实践资料
在 GitHub 上编辑此页
最后更新: 3/20/26, 6:06 AM
贡献者: cuihairu