PHP 8.0 本身不引入SQL注入风险,漏洞仅存在于应用层错误写法:如手动拼接SQL、滥用whereRaw()未绑定参数、order/group直传用户输入、Db::raw()内嵌变量等;安全前提是坚持参数化查询与白名单校验。

检测 PHP 8.0 网站是否存在 SQL 注入漏洞,关键不是“用什么工具”,而是搞清请求参数是否真正参与了未防护的 SQL 拼接。PHP 8.0 本身不引入新注入风险,但运行在其上的应用若存在拼接写法、绕过预编译或误用框架方法,漏洞依然存在。
先确认三个必要前提
跳过这步直接发 payload,90% 的测试会误判:
-
参数是否进入 SQL 查询逻辑:比如
?id=1最终是否变成WHERE id = 1这类拼接?可通过修改为?id=1' and '1'='1观察报错或行为变化来初步验证; -
后端是否关闭错误回显:PHP 配置中
display_errors=Off或代码里error_reporting(0)会让 MySQL 报错消失,但不代表没漏洞——盲注仍可进行; -
WAF 是否拦截基础探测:尝试
?id=1' OR '1'='1返回 403 或空响应,说明有规则拦截,后续需绕过(如大小写、编码、注释符变形)。
用 ORDER BY 和 UNION SELECT 快速验证回显
适用于页面能直接看到数据库返回内容的场景(比如商品列表、用户详情):
- 先测字段数:
?id=1 ORDER BY 3--成功,?id=1 ORDER BY 4--报错 → 说明查询结果有 3 列; - 再试回显点:
?id=-1 UNION SELECT 1,2,3--,看数字 1/2/3 是否出现在页面中; - 成功后替换为关键信息函数:
UNION SELECT VERSION(), DATABASE(), USER()--,确认能否读出数据库环境; - 注意 MySQL 5.7+ 对
NULL类型敏感,若报错可改用字符串占位:UNION SELECT 'a','b','c'--。
布尔盲注和时间盲注的实用判断法
当页面只显示“成功”或“失败”(如登录页提示“用户不存在”),需靠逻辑响应差异探测:
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
立即学习“PHP免费学习笔记(深入)”;
- 布尔型:发
?id=1 AND ASCII(SUBSTR(DATABASE(),1,1)) > 100,对比> 110的响应差异,逐位猜解; - 时间型更稳妥:
?id=1 AND IF(ASCII(SUBSTR(DATABASE(),1,1))=114, SLEEP(2), 1),观察响应延迟是否明显大于平均值(建议 sleep 时间设为服务端平均响应时间的 2 倍以上); - 防限速技巧:每次请求加随机
User-Agent和Referer,避免被 WAF 或应用层频率策略封 IP。
ThinkPHP 6.x(常被误称 TP8.0)特别注意点
目前无 ThinkPHP 8.0 官方版本,实际多为 TP6.x 运行在 PHP 8.0+ 环境。其模型方法如 where('id', $input) 默认安全,但以下写法仍高危:
-
whereRaw("status = $status")—— 应改为whereRaw("status = ?", [$status]); -
order(input('sort'))—— 动态排序必须白名单校验:in_array($sort, ['id', 'create_time']); -
Db::raw("{$input} * 10")被嵌入到where或select中 —— 一旦变量进 raw,就脱离所有防护。
不复杂但容易忽略:真正决定有没有注入的,从来不是 PHP 版本或框架名字,而是那一行把用户输入直接塞进 SQL 字符串的代码。


















