为什么参数化查询能够有效阻止SQL注入攻击

老伟姑娘_1383

老伟姑娘_1383

2026-10-25

668人浏览

原创

参数化查询能阻止SQL注入,因其在数据库预编译阶段即锁定SQL语法结构,用户输入仅作为纯数据在执行阶段填入内存缓冲区,不参与词法/语法分析;它只保护“值”,不保护表名、列名等结构部分,后者须白名单校验。

为什么参数化查询能够有效阻止sql注入攻击

参数化查询能阻止SQL注入,是因为它从数据库执行流程的最底层切断了“把用户输入当代码执行”的可能性。不是更谨慎,而是根本没机会解析成代码。

数据库预编译阶段就锁死语法结构

当你调用 cursor.execute("SELECT * FROM users WHERE name = %s", (user_input,))

数据库收到的不是一条完整可执行的 SQL 字符串,而是两件事:第一,一条带占位符的模板(如 SELECT * FROM users WHERE name = $1),被送入解析器生成固定执行计划;第二,user_input 的值作为纯数据,在执行阶段才填进内存缓冲区,不参与任何词法或语法分析。

哪怕 user_input 是 ' OR 1=1 --,数据库也只把它当一个长度为 12 的字符串字面量塞进 $1,不会去闭合引号、不会触发注释、更不会重写 WHERE 条件。

常见错误理解:

  • 以为“用了 ? 或 %s 就安全”——错,如果这串 SQL 是用 f-string 拼出来的再传给 execute,参数化就完全失效
  • 以为“过滤了单引号就没事”——PostgreSQL 支持 Unicode 引号,MySQL 支持反引号绕过,驱动对空字节或编码混淆可能不敏感

参数化只保护“值”,不保护“结构”

表名、列名、ORDER BY 字段、GROUP BY 表达式这些属于 SQL 语法结构的一部分,数据库不允许也不支持对它们做参数绑定。

AiBiao.cn
AiBiao.cn

一款AI数据处理工具,主要用于一句话自动生成图表,适合需要提升相关任务效率的用户。

下载

下面这些写法依然高危:

  • "SELECT * FROM " + table_name + " WHERE id = ?" —— table_name 是拼接的,? 救不了它
  • "ORDER BY " + sort_field + " " + direction —— 必须靠白名单校验 sort_field 是否在 ["id", "name", "created_at"] 中
  • MyBatis 里写 SELECT * FROM user WHERE status = ${status} —— ${} 是字符串替换,不是参数绑定

ORM 的原始查询接口(如 Sequelize 的 query()、Prisma 的 $queryRawUnsafe)也一样:只要用户输入进了 SQL 字符串本体,参数化就形同虚设。

不同语言里参数化是否真正生效,取决于驱动是否走预编译路径

不是所有占位符语法都等价。关键看底层是否把 SQL 模板和参数分两次发给数据库。

  • Python 的 psycopg2 用 %s、sqlite3 用 ?,只要调用的是 cursor.execute(sql, params),就走安全路径
  • Node.js 的 pg 驱动必须用 client.query('SELECT ...', [value]);若写成 client.query(`SELECT '${value}'`),哪怕 value 经过转义也不保险
  • Java 的 PreparedStatement 是标准,但若用 Statement + String.format 拼接,等于裸奔
  • PHP 的 PDO::prepare() + execute() 安全;mysql_query()(已废弃)或 mysqli::query() 直接拼接则危险

真正容易被忽略的点是:参数化是否生效,不看你写了什么符号,而看你有没有让驱动把参数单独序列化传输。一旦参数混进 SQL 字符串里,就回到拼接的老路。

最危险的不是不会用参数化,而是误以为用了就万事大吉——尤其是当动态表名、排序字段、搜索通配符(LIKE '%${q}%')混在同一个查询里时,一个没守住,整条链就崩了。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

4523

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

951

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1189

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

6501

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

3263

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

6460

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

8861

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1210

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1052

5

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP开发基础之数据库篇(PDO)
PHP开发基础之数据库篇(PDO)

共10课时 | 2.3万人学习