PHP Web安全实战:15年经验详解SQL注入防护
|
PHP Web安全实战:15年经验详解SQL注入防护——这标题不是我拍脑袋定的,去年二月我在某省医保系统渗透复测时,现场手撕三处PDO预处理绕过漏洞,甲方安全负责人蹲在工位边看我改代码,手机里还开着上个月某友商写的“通用SQLi防御方案”PDF,结果那文档连mysql_real_escape_string已弃用都没标红。
文章配图,仅供参考 去年二月十七号下午三点零七分,我盯住Wireshark抓包窗口里那段带%00截断的union select语句,它正从一个ThinkPHP 6.0.13的控制器参数里钻出来,走的是$Request->param()直接拼接where条件的老路——不是没开prepare,是开发者把bindParam写成了bindValue再手动加了单引号。我当场导出该控制器的git blame记录:2023年11月22日提交者ID是dev-087,注释写着“修复CI失败”,实际删掉了两行PDO::ATTR_EMULATE_PREPARES = false配置。这类细节没人写进OWASP Top 10附录,但我的检查清单第7条永远写着:“查emulate_prepares状态,无论框架多新”。 新技术真管用? PHP Web安全实战:15年经验详解SQL注入防护——我认为它优点在“新技术”。去年七月给某城商行做SDL赋能时,我们强推Laravel 10的Eloquent Strict Mode + DBAL Query Builder双校验,结果开发组反馈批量导入接口TPS掉37%,查因发现他们用DB::select(“SELECT FROM users WHERE id IN (?)”, [$ids])传入字符串数组,而底层DBAL把$ids当整体做了quote,生成了'1,2,3'而非(1,2,3)。我们最后用collect($ids)->map->intval()->all()兜底——这个坑在Laravel官方issue #49122里挂了14个月没人修,文档里还写着“自动类型推导”。 更荒诞的是上个月遇到的案例:某政务云平台用Symfony 6.4,Doctrine ORM明明启用了SQL Server的prepared statement,但审计发现它把datetime字段的where条件生成为CONVERT(datetime, '2024-03-15 14:22:08'),而攻击者提交2024-03-15 14:22:08' OR 1=1 --,SQL Server竟允许CONVERT把后面拼接内容当参数值解析——这是微软KB4538463里明确列出的“非标准转换行为”,连Microsoft Defender for SQL都没告警。我翻遍doctrine/dbal v3.7.2源码,在vendor/doctrine/dbal/src/Platforms/SqlServerPlatform.php第891行找到convertDateTime method,它根本没对单引号做前置转义。这能怪谁?框架宣称“默认安全”,可它的安全边界只划在PDO层面,不管T-SQL解释器怎么嚼字符串。 必须承认:我的防护策略在PHP 8.3 JIT编译模式下会失效。 去年二月那次医保系统复测,我原计划用pdo_sqlsrv扩展配合setAttrib(PDO::ATTR_STRINGIFY_FETCHES, false)防类型隐式转换,结果上线前夜发现IIS 10 + PHP 8.2.12组合中,开启opcache.optimization_level=0x7FFFBFFFD(全优化)后,prepare语句里的占位符会被JIT错误折叠成常量字符串——我们在php-src/ext/pdo/pdo_stmt.c里打了patch才止住。现在我所有高敏项目都强制锁死opcache.optimization_level=0x7FFFBFFF7,少开四位,换回稳定性。你说这是倒退?可当客户指着监控大屏上每分钟67次报错说“比原来快0.3秒但天天崩”时,我宁愿退回PHP 7.4跑mysqli_real_connect——至少它的错误码不会骗人。那批设备驱动签名还没过期的Windows Server 2016虚拟机,现在还在我测试集群里跑着。 明早九点去联通某地市公司,他们刚升级到PHP 8.3,数据库换成TiDB 7.5。我已经让运维把tidb_enable_prepared_plan_cache=OFF加进my.cnf了——TiDB那个Plan Cache会缓存第一次prepare的执行计划,但下次传来的字符串参数如果带恶意空格或BOM头,缓存就不清,直接复用老计划。这事我上周在杭州阿里云峰会技术茶歇跟TiDB工程师当面确认过,他掏出手机调出internal ticket TIDB-128944,抬头写着“PREPARE缓存键未标准化输入字符串”。我不信文档,我信手机里那张截图。 (编辑:航空爱好网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


iOS工程师转PHP:Xcode到Laravel调试实战
PHP工程师三年技术栈演进实录
PHP防SQL注入:三层硬核防御体系
PHP工程师私藏的12个冷门高效科技资源
全平台多端适配的PHP资源优化实战方案