SQL 注入:参数化查询为什么能根治

Web安全 · 3 分钟阅读· 291 次阅读

SQL 注入不新鲜,但每年仍在 OWASP 前十。原因不是大家不知道,而是「拼接更方便」。

理解一个点就够了:只要用户输入进入了 SQL 语句的语法结构,就有注入风险——不管它看起来多安全。

先说结论

所有变量走参数化,排序/表名走白名单,数据库账号只给必要权限。

  • 参数化查询让数据库把输入当数据而非语法
  • ORDER BY / LIMIT / 表名无法参数化,必须白名单
  • ORM 的 raw 查询是重灾区
  • 数据库账号禁止 FILE/SUPER 权限

漏洞是怎么产生的

SQL 的解析分两步:先编译语法结构,再代入数据。拼接字符串会让用户输入参与到第一步,于是 ' OR 1=1 -- 变成了语法的一部分。

参数化查询把「结构」和「值」分开传给数据库,结构先编译,值只当数据。这是从机制上杜绝,不是过滤。

修复与验证

修复不是改一行代码,而是四件事一起做:

  • 全量排查拼接 SQL:搜索字符串拼接 + 查询执行的位置
  • 改为参数化(占位符),包括 IN 列表的动态占位
  • 排序字段、表名、列名改为枚举白名单映射
  • 检查 ORM 的 raw/execute 调用,同样要参数化
  • 数据库账号降权:只授予业务需要的 SELECT/INSERT/UPDATE/DELETE

攻击面与检测点

按影响面排序,先修影响最大的:

入口 风险点 修法
查询参数 拼接 WHERE 参数化占位符
排序/分页 ORDER BY 拼接 白名单映射
搜索框 LIKE 拼接 参数化 + 转义通配符
ORM raw 原生 SQL 参数绑定

SQL 注入

几个容易踩的坑

下面这些是最常见的错误做法:

  • 用 addslashes/转义代替参数化:宽字节与数字型仍可绕
  • 只在前端校验:抓包即可绕过
  • 过滤 select 关键字:注释、大小写、编码都能绕
  • 忽略二次注入:数据入库后再拼接

写在最后

判断标准很简单:代码里还有没有「变量拼进 SQL 字符串」。有就改,别讨论是否可利用。

安全不是一次加固,是持续的假设:假设输入不可信、假设边界会破、假设有人会看错。

评论 (3)

半
半箱油

修复清单比漏洞描述有用多了,很多文章只讲怎么打不讲怎么防。

白
白帽小林

白名单那条永远是最有效的,正则黑名单迟早绕过。

运
运维老张

建议再补一条:把这类检查加到 CI 里,靠人记必然漏。

发表评论

验证码

提交后需站长审核,通过后才会显示。