必须立即检查php项目中preg_match等正则函数调用是否存在回溯灾难、拒绝服务或校验绕过风险,重点审计config/、app/http/controllers/、routes/目录下含嵌套量词如(a+)+的高危模式,并通过pcretest实测回溯步数,优先用原子组(?>)或先行断言替代。

发现PHP框架项目中正则表达式被用于路由匹配、输入校验或模板解析时,必须立刻检查是否存在回溯灾难、恶意构造导致的拒绝服务或绕过校验逻辑的问题。
识别正则使用位置
在框架代码中全局搜索 【preg_match】、【preg_replace】、【preg_split】 和 【preg_filter】 四个函数调用点,重点关注 config/、app/Http/Controllers/、routes/ 目录下的 PHP 文件。
用 grep -r "preg_[a-z]*(" --include="*.php" app/ config/ routes/ | grep -v "vendor/" 命令快速定位——漏掉 vendor 目录是常见错误,但审计目标应聚焦业务代码,第三方库暂不纳入首轮检查范围。
判断是否启用 PCRE JIT 编译
执行 php --ri pcre 查看输出中是否含 “PCRE JIT support => enabled”。若为 disabled,所有复杂正则都更易触发回溯爆炸,需优先处理。
在 php.ini 中添加 pcre.jit=1 并重启 PHP-FPM 仅治标;真正要改的是正则本身,不是靠 JIT 掩盖缺陷。
检查正则模式是否含危险量词组合
方法一:人工筛查高频风险结构
逐行检查每个正则字符串,重点抓取形如 【.*?a.*?b】、【(.*)+】、【(a+)+】、【(a|aa)+】 的子模式——这类嵌套量词叠加极易引发指数级回溯。
方法二:用 pcretest 工具验证回溯步数
第一步:将待测正则复制进 test.reg 文件,格式为 /pattern/u(注意保留修饰符);
第二步:准备恶意测试字符串,例如对 /^(a+)+b$/ 使用 30 个 a 加一个 c;
第三步:执行 pcretest -i test.reg,观察输出中 “Match returned” 后是否出现 “partial match” 或卡住超过 3 秒——卡顿即表明存在回溯隐患。
这一步不能跳过,光看正则写法无法确认实际执行行为,必须实测。
替换高危正则为原子组或固化断言
将 (a+)+ 改为 (?>a+)+,把 .*?user.*?pass.*? 改成 (?=.*user)(?=.*pass)^.*$;前者禁用回溯,后者转为先行断言避免贪婪匹配失控。
注意:(?!) 和 (?>) 不是所有 PHP 版本都支持,PHP 7.3+ 才完整支持原子组语法,低于该版本需改用非捕获组 + 显式锚点控制,例如用 ^(?:[^a]*a){1,5}[^a]*$ 替代 a{1,5} 的模糊匹配。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











