AJAX返回含%通配符的URL触发ModSecurity 403禁止错误求助
问题背景
请求URL https://simple.com/forms/test/listrecord.php?page=2&fp=0&sql_where=fullname like ? and active = ?¶ms='%ABCDE%'|1&element_id=hello 触发ModSecurity 403拦截,移除ABCDE两侧的%后可正常访问,核心原因是ModSecurity的SQL注入防护规则误将%通配符识别为恶意注入字符。
以下是几种可行的解决办法:
服务器端调整ModSecurity规则
找到ModSecurity的规则配置(比如OWASP CRS规则集),定位拦截%的SQLi检测规则(常见规则ID如942100)。可以给目标URL或参数添加规则例外:SecRule REQUEST_URI "@beginsWith /forms/test/listrecord.php" "id:1000,phase:1,nolog,allow,ctl:ruleRemoveById=942100"也可以修改规则敏感度,放宽对合法LIKE通配符的检测阈值,减少误判。
前端对参数进行URL编码
在AJAX发送请求前,把params里的%转成URL编码%25,修改后的参数值为'%25ABCDE%25'|1。服务器接收后会自动解码为%ABCDE%,同时绕过ModSecurity的原始字符检测。示例JS代码:let params = "'%ABCDE%'|1"; params = encodeURIComponent(params); // 用编码后的params拼接请求URL后端改用预编译语句绑定参数
不要让前端传入带%的参数,后端自己处理通配符。比如PHP中用PDO预编译:// 拆分前端传入的params得到查询值和状态值 list($likeVal, $activeVal) = explode('|', str_replace(["'", '%'], '', $_GET['params'])); $stmt = $pdo->prepare("SELECT * FROM your_table WHERE fullname LIKE ? AND active = ?"); // 后端添加通配符 $stmt->execute(["%{$likeVal}%", $activeVal]);这种方式既避免了WAF拦截,还从根源上杜绝SQL注入风险,比依赖WAF更安全。
测试环境临时禁用规则(不推荐生产用)
如果是测试阶段,可以临时关闭对应的ModSecurity规则验证问题,但生产环境一定要用更安全的例外或编码方案,不能直接关闭防护规则。
内容的提问来源于stack exchange,提问作者Sachin

