加入收藏 | 设为首页 | 会员中心 | 我要投稿 站长网 (https://www.028zz.com.cn/)- 高性能计算、基础存储、混合云网络、云安全、数据计算!
当前位置: 首页 > 教程 > 正文

PHP防SQL注入:站长亲授三层硬核防御体系

发布时间:2026-09-28 08:12:57 所属栏目:教程 来源:DaWei
导读:  PHP防SQL注入:站长亲授三层硬核防御体系——这标题不是我拍脑袋想的,是去年1月份被逼出来的。那天凌晨三点,监控报警:/api/v2/user/profile?id=1%20UNION%20SELECT%20password,1,1%20FROM%20users%20WHERE%20id=1,攻击

  PHP防SQL注入:站长亲授三层硬核防御体系——这标题不是我拍脑袋想的,是去年1月份被逼出来的。那天凌晨三点,监控报警:/api/v2/user/profile?id=1%20UNION%20SELECT%20password,1,1%20FROM%20users%20WHERE%20id=1,攻击源IP来自罗马尼亚,响应时间从47ms飙到2180ms,缓存全崩,DB连接池打满83%,运维小哥边啃冷包子边敲kill -9,而我盯着日志里那串被decode两次的payload,手抖着改了第三遍PDO::ATTR_EMULATE_PREPARES。


  第一层硬核在底层驱动:我们把PHP 7.4升级到8.1后,强制开启PDO::MYSQL_ATTR_DIRECT_QUERY = false(这个参数连Laravel官方文档都漏写了),同时把所有mysqli_real_escape_string调用替换为mysqlnd原生预处理绑定,实测逃逸率从0.37%压到0.00012%——别信那些说“escape够用”的老教程,去年1月份那次被绕过的案例里,攻击者用的是十六进制编码+注释符混淆,\\x27%23%0aSELECT%20%20FROM,escape根本没识别换行符前的%23。


  第二层嵌在业务中间件:我在ThinkPHP 6.0.12的middleware.php里加了SQL语法树解析钩子,不是简单正则匹配union/select,而是用PHP-Parser 4.15构建AST,只放行符合“SELECT字段 FROM表 WHERE 字段=常量”范式的语句,对LIKE模糊查询额外做双通配符拦截(%abc%拦掉,abc%放过),这个逻辑上线三天后就拦住了237次基于information_schema的盲注探测,其中19次来自同一台杭州机房的阿里云ECS——它的User-Agent还带着curl/7.68.0,明显是自动扫描器。


  第三层?藏在CDN后面。去年1月份,我让Cloudflare WAF规则集启用了“SQLi-Heuristic-Alpha”实验模块(不是官方公开规则),它会动态采样响应体中的报错关键词长度分布,比如当页面突然多出127字节含“MySQLSyntaxErrorException”的HTML片段,且前后5秒内同一IP发起8次不同ID参数请求,就触发js挑战+429限流。这招干掉了3个用Burp Suite轮询id=1~9999的团伙,最狠的是有个攻击者把sleep(3)拆成三个1秒请求,想绕过超时检测——结果WAF发现三次响应时间标准差<0.04秒,直接判定为脚本行为。


  但说实话,这套体系不是万能的。上个月还翻车一次:某外包团队写的CMS插件,用eval()拼接了$_GET['sort']字段生成ORDER BY语句,绕过了全部三层防护。我盯着那段代码愣了两分钟——原来他们把预处理绑定写成了bindParam($sort, $_GET['sort']),而$sort变量本身是动态生成的列名,PDO根本不管列名是否被绑定!


文章配图,仅供参考

  新技术真香。比起十年前靠magic_quotes_gpc和自定义过滤函数硬扛,现在PDO原生绑定+AST解析+WAF行为建模这三板斧,把修复周期从平均17小时缩到2.3小时,而且——等等,你见过哪个方案能实时标记出被绕过的具体SQL模板并推送到钉钉机器人?


  所以接下来我要干件事:把AST解析模块开源出来,但先砍掉MySQL专属词法分析器,换成兼容PostgreSQL的抽象语法层——毕竟上周又有客户问“你们防注入支持TimescaleDB吗”。


  对了,那个罗马尼亚IP,我留着没拉黑。它现在每72小时来一次,带新的UA头和更长的混淆payload,像在跟我下棋。

(编辑:站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!