ModSecurity 不能替代 phpMyAdmin 升级,必须先升级至 ≥5.2.0 版本修复SQL拼接漏洞,再通过 Nginx 正确加载 modsecurity 模块、开启 SecRequestBodyAccess、透传请求体,并配置针对 sql.php/import.php 路径及 union/select 等特征的精准 deny 规则,同时屏蔽 config.inc.php 文件访问。

ModSecurity 本身不能直接“防护 phpMyAdmin”,它只在 Nginx 或 Apache 的请求入口处做规则匹配;而 phpMyAdmin 是个 PHP 应用,若已存在高危 SQL 拼接逻辑(比如老版本未打补丁),ModSecurity 只能拦住常见变形注入,拦不住绕过规则的定制 payload。真正有效的防护必须分层:先升级 phpMyAdmin 到 ≥5.2.0(已修复多处 sql.php 和 import.php 的拼接漏洞),再用 ModSecurity 做兜底过滤。
确认 nginx 已编译 modsecurity 动态模块
没这一步,所有 SecRule 都是废配置——Nginx 启动会报 unknown directive "SecRule"。运行:
nginx -V 2>&1 | grep -o modsecurity
必须输出非空(如 modsecurity 或路径)。Debian/Ubuntu 用户可直接装 nginx-mod-http-modsecurity 包;CentOS/RHEL 必须源码编译 libmodsecurity + nginx-modsecurity,且 load_module 路径要写绝对路径,例如:load_module /usr/lib64/nginx/modules/ngx_http_modsecurity_module.so;
验证是否真正加载成功:ldd $(which nginx) | grep modsecurity 有输出才算链上。
立即学习“PHP免费学习笔记(深入)”;
必须开启 SecRequestBodyAccess 并透传原始 body 给 PHP-FPM
phpMyAdmin 的注入点集中在 POST 请求体(如 sql.php?session_max_limit=100 后跟 raw SQL),但默认 SecRequestBodyAccess Off,OWASP CRS 的 REQUEST-942-APPLICATION-ATTACK-SQLI.conf 根本不看 REQUEST_BODY。
在 modsecurity.conf 中加:
SecRequestBodyAccess On
同时,在 Nginx 的 phpMyAdmin location 块中必须显式透传:
-
proxy_pass_request_body on;(若用 proxy_pass) -
fastcgi_pass_request_body on;(若用 fastcgi_pass,这是绝大多数 phpMyAdmin 部署方式)
漏掉任一,ARGS 和 REQUEST_BODY 都为空,规则永远不触发。
针对 phpMyAdmin 特征路径和参数加固规则
CRS 默认规则对 phpMyAdmin 不够敏感——它不识别 sql_query、import_text 这类专用参数名,也不覆盖 sql.php 的 GET+POST 混合攻击场景。
建议在 nginx.conf 的 phpMyAdmin location 内追加这几条:
ModSecurityEnabled on;<br>SecRule REQUEST_URI "@rx (?i)^/phpmyadmin/(sql|import)\.php$" "id:1001,phase:1,pass,nolog,tag:'phpmyadmin'"<br>SecRule ARGS_NAMES|ARGS|REQUEST_BODY "@rx (?i)(union\s+select|select\s+.*\s+from|insert\s+into|drop\s+table|load_file)" "id:1002,phase:2,deny,status:403,msg:'phpMyAdmin SQLi detected'"<br>SecRule REQUEST_METHOD "POST" "id:1003,phase:1,pass,nolog,tag:'phpmyadmin-post'"<br>SecRule REQUEST_BODY "@rx \x00" "id:1004,phase:2,deny,status:403,msg:'Null byte in phpMyAdmin body'"
注意:phase:2 才能访问到解码后的 REQUEST_BODY;@rx 正则要加 (?i) 忽略大小写;\x00 检查用于拦截 null-byte 注入(老版本 phpMyAdmin 存在此类 bypass)。
绕过 CRS 的常见手法及应对
攻击者对 phpMyAdmin 下发 UNI%6fN SEL%65CT 或 SEL/**/ECT,CRS v3.3+ 的 t:urlDecodeUni,t:lowercase 在 Nginx 链路中容易失效——因为 Nginx connector 解析时可能只做一次 URL decode,二次编码被忽略。
稳妥做法是手动补全转换链:
SecRule ARGS|REQUEST_BODY "@rx union\s+select" "t:urlDecodeUni,t:lowercase,id:1005,phase:2,deny,status:403,msg:'Decoded UNION SELECT'"
不要只依赖 CRS 的累加式异常分值(TX:ANOMALY_SCORE),phpMyAdmin 是高危目标,应启用明确 deny 动作;同时检查 SecResponseBodyAccess Off,避免响应体解析拖慢管理界面。
最易被忽略的是:phpMyAdmin 的 config.inc.php 若暴露在 Web 可访问路径下,ModSecurity 规则再强也拦不住直接下载配置文件读取数据库凭据——务必确保该文件不在 location / 范围内,或用 location ~ ^/config\.inc\.php$ { deny all; } 硬屏蔽。



















