You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

字符串拼接的PDO SQL查询能否抵御注入?求解

字符串拼接SQL加了分号依然不安全,预处理才是正道

兄弟,先给你拍板:这种用字符串拼接生成SQL的写法绝对不安全,哪怕你特意给语句加上分号结尾,也挡不住SQL注入攻击,别抱有任何侥幸心理。

举个最直白的例子,假设你的$id变量被攻击者传入了这样的值:'1; DROP TABLE my_table;--'

那你拼接后的SQL就会变成:

SELECT * FROM `my_table` WHERE `pk_id` = '1; DROP TABLE my_table;--';

数据库执行这条语句的时候,会先跑完前面的SELECT查询,接着执行后面的DROP TABLE——直接把你的表删了!后面的--是SQL注释符,会把最后那个多余的分号注释掉,让整个恶意语句合法执行。

你以为加个分号就能截断恶意代码?太天真了,攻击者有一百种方式绕过这种“手动防护”。

为什么预处理语句能确保安全?核心在于参数化查询:

  • 预处理是先把SQL的结构(比如SELECT * FROM my_table WHERE pk_id = ?)发给数据库编译,数据库会先确定这条语句的执行逻辑;
  • 之后再把$id作为纯参数传入,数据库会把参数当成普通数据处理,不会把参数里的任何特殊字符(分号、引号、注释符)解析成SQL指令。

哪怕攻击者传入再恶意的参数,也只会被当成pk_id字段的查询值,不会触发额外的SQL操作。

顺便提一句:别想着自己手动过滤参数来替代预处理,手动过滤很容易有遗漏——比如编码转换、特殊字符的变种、不同数据库的语法差异,这些都可能让你的过滤失效。预处理是业界公认的、最可靠的防SQL注入方案。

最后给你改写成安全的预处理写法:

$pdo = new PDO($dsn, $usr, $pass);
// 用占位符?定义参数位置
$stmt = $pdo->prepare('SELECT * FROM `my_table` WHERE `pk_id` = ?;');
// 传入参数数组执行
$stmt->execute([$id]);
// 获取结果
$res = $stmt->fetchAll();

内容的提问来源于stack exchange,提问作者treyBake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:19:16