位置:首页 > SQL > 如何防止SQL排序参数注入风险与安全处理方法

如何防止SQL排序参数注入风险与安全处理方法

时间:2026-08-21  |  作者:星际追番人  |  阅读:0

ORDER BY后的列名和排序方向无法参数化,必须通过白名单校验并配合数据库特定的标识符转义(如MySQL用反引号、SQL Server用QUOTENAME)来防止SQL注入。

如何防止排序参数造成SQL注入

ORDER BY 后的列名不能用参数化查询

这一点常常被误解:数据库不支持将 ORDER BY 后的列名或排序方向(ASC/DESC)当作参数绑定。当你写成 ORDER BY 或者 ORDER BY @col 时,绝大多数数据库会直接报错,这是因为列名属于SQL语法结构,并非“值”。强行将其塞进参数占位符,只会引发语法错误,而无法安全执行。

白名单校验是唯一可靠方案

对用户传入的排序字段(如 $_GET['sort']@sort_column),必须严格限制为预定义的合法值。这不是“建议”,而是强制要求。

  • 明确列出所有允许的列名,比如 ['id', 'name', 'created_at', 'status'],其余一概拒绝
  • 排序方向必须单独校验,只接受 'ASC''DESC',且转为大写后再比对(避免大小写绕过)
  • 不要用 in_array($input, $whitelist, true) 就完事——确保输入未被截断、未含不可见字符(如零宽空格、BOM)
  • 若需支持多字段排序(如 name,created_at DESC),应拆解后逐字段白名单校验,再拼接,而非整段放行

拼接前必须用 quotename 或 identifier escape

即使通过了白名单,拼接到 SQL 中时仍可能因特殊字符(如带空格的列名 [user name] 或含中划线的 first-name)引发语法错误或注入风险。不同数据库 escape 方式不同:

  • SQL Server:用 QUOTENAME(@col) 包裹列名,它自动加 [] 并转义内部 ]
  • PostgreSQL:用双引号 "col_name",但需手动替换双引号为两个双引号("""
  • MySQL:用反引号 `col_name`,注意不能直接拼接用户输入,必须先过滤非法字符(如反引号本身)
  • PHP 中若用 PDO,没有内置 identifier escape 函数,得自己实现或依赖 DBAL 类库

别信“过滤关键词”或“正则黑名单”

试图靠 str_replace([';', '--', '/*'], '', $input) 或正则匹配 /union|select|drop/i 来防排序注入,基本无效。

  • 攻击者可用 Unicode 同形字(如全角 ASC)、嵌套注释(/*/**/ORDER)、大小写混用(OrDeR)绕过
  • 哪怕过滤掉所有关键字,只要列名拼接未 escape,仍可能因注入式标识符(如 name]; DROP TABLE users--)触发语句截断或执行异常
  • 这类过滤还容易误杀合法字段名(如列名含 user_id,被误判为 user 关键词)

白名单 + 正确 escape 是唯一路径。漏掉任一环节,都等于在 ORDER BY 后留了一扇没锁的门。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多