sql盲注更难防因不回显错误,依赖布尔响应或时间延迟探测,waf和日志难以识别;需最小化mysql权限、禁用高危操作、严格白名单校验动态sql部分,并杜绝拼接。

SQL盲注为什么比报错注入更难防
因为盲注不回显错误,攻击者靠布尔响应或时间延迟判断数据真假,传统WAF和日志监控很难捕捉。你看到的只是正常HTTP 200响应,但背后可能已在逐字猜解information_schema里的表名。
MySQL用户权限必须按最小原则重配
很多线上库用root或app_user@'%'直连,这是盲注成功的温床。一旦应用层拼接了用户输入,攻击者就能借该账号权限跑SLEEP()或IF(1=1, BENCHMARK(1000000,MD5('a')))。
- 应用专用账号只授予
SELECT、INSERT等必要权限,禁用FILE、PROCESS、SHOW DATABASES - 限制主机范围,把
app_user@'10.20.%.%'换成app_user@'10.20.30.40'(具体应用服务器IP) - 禁用
mysql.user表的直接查询:执行REVOKE SELECT ON mysql.* FROM 'app_user'@'%'
预编译语句不是万能的,但必须用且要彻底
很多人以为用了mysqli_prepare()就安全了,结果在WHERE里拼接了ORDER BY ?——参数占位符不能用于列名、表名、关键字。这时候盲注依然成立。
-
ORDER BY、GROUP BY、LIMIT偏移量等动态部分,必须走白名单校验,比如:if (!in_array($sort_field, ['created_at', 'status'], true)) die('invalid sort'); - PHP中避免
mysqli_real_escape_string()混用:它对'转义有效,但对1 OR SLEEP(1)这类无引号payload完全无效 - Java里用
PreparedStatement时,别在SQL字符串里拼" WHERE id = " + id——占位符必须覆盖所有动态值
SQL白名单机制要落地到具体字段和操作
所谓“白名单”不是指允许哪些SQL模板,而是限定哪些字段可被用户控制排序、搜索、分页——否则容易变成“白名单里的黑逻辑”。
- 搜索字段只能是
title、content(需配合全文索引),禁用id、created_at等易被用于时间盲注的字段 - 对
LIKE查询强制加前后缀:WHERE title LIKE CONCAT('%', ?, '%'),防止%被用户控制导致全表扫描+延时差异暴露 - 开启
slow_query_log并设long_query_time = 0.5,重点盯BENCHMARK、SLEEP、嵌套子查询类慢SQL,它们常是盲注探测痕迹
真正难防的不是技术方案,而是业务代码里那些“临时加个排序参数”“前端传个字段名后端直接拼”的妥协。白名单不是配置项,是每次$_GET['order']进来时,代码里那一行硬编码的in_array校验。漏掉一次,就可能让整套防御失效。











