首页/安全/渗透测试与安全评估速查/SQL 注入修复视角:参数化查询
常见漏洞验证121 条

SQL 注入修复视角:参数化查询

参数化查询(预编译)让数据与语句结构分离,是根治注入的手段;无法参数化的排序、表名等位置必须用白名单映射。

SQL 注入修复视角

SQL 注入的根治手段是参数化查询(预编译):让 SQL 语句的结构在执行前确定,用户输入只作为参数数据传入,与语句结构彻底分离,输入中即使含引号与逻辑运算符也无法改变语句语义。需要注意,并非所有位置都能参数化——表名、列名、排序方向这类标识符无法用占位符替代,必须用白名单映射(代码中定义允许的固定值集合,逐项对应)。修复复查时重点关注三处:ORM 的 raw 或 execute 拼接、动态拼装的分页与筛选条件,以及存储过程内部的动态 SQL,这三处是参数化改造最常见的遗漏点。

基本信息

根治手段占位符绑定参数(? 或命名占位符)
例外位置表名、列名、排序方向用白名单映射
复查点ORM 原生 SQL、拼接的分页与动态条件
临时缓解转义与黑名单过滤,不能替代参数化
验证方式修复后复测原注入点与等价路径

典型使用场景

  • 修复方案评审:确认改造是否覆盖全部查询路径
  • ORM 项目:排查 raw、execute 与拼接语句的调用点
  • 动态排序:把用户选择的排序字段映射为固定列名
  • 存储过程:检查内部动态 SQL 是否同样需要参数化
  • 复测验证:对原问题点与等价请求做回归验证

修复示意(伪代码)

修复示意(伪代码)
不安全:语句 = SELECT * FROM orders WHERE id = + 用户输入
安全:  语句 = SELECT * FROM orders WHERE id = ?,以参数绑定用户输入
动态排序:
不安全:ORDER BY + 用户输入
安全:  ORDER BY 白名单映射[用户输入](仅映射到固定列名)

位置与手段

位置可否参数化手段
WHERE 条件值可行占位符绑定参数
INSERT 与 UPDATE 值可行占位符绑定参数
表名与列名不可行白名单映射到固定标识符
排序方向不可行映射为 ASC 或 DESC 固定值
LIMIT 与 OFFSET可行绑定整型参数并做范围校验
存储过程动态 SQL可行过程内部同样使用参数化拼装
字符串转义与黑名单过滤只能作为临时缓解,不能替代参数化;更换数据库方言时过滤规则往往失效。
ORM 的 raw 与 execute 拼接仍然可以注入,需要逐个复查;存储过程内部的动态 SQL 同样需要参数化。

易错点

  • ORM 的 raw 或 execute 拼接仍然可注入,需逐个复查调用点
  • 存储过程内部的动态 SQL 未参数化,修复只做了一半
  • 用转义或黑名单当作修复方案,换方言或编码后失效
  • 只修复报告中的单一注入点,未排查同类参数的其他查询

数据来源与参考

  • OWASP Cheat Sheet Series:SQL Injection Prevention
  • CWE-89
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌