默认CRS规则对phpMyAdmin几乎必然误杀,因其不区分管理后台语义,直接在sql_query、import_text等合法含SQL关键字的字段中匹配正则模式即返回403;须按路径+参数两级放行,禁用LFI/SQLi规则对特定字段的检测,而非关闭整条规则链或全局禁用。
不能直接套用owasp crs默认规则集拦截phpmyadmin的恶意攻击——它会把合法sql查询(如select * from users)当成sql注入干掉,导致登录失败、导入中断、表结构加载空白。
为什么默认CRS规则对phpMyAdmin几乎必然误杀
OWASP CRS的REQUEST-942-APPLICATION-ATTACK-SQLI和REQUEST-930-APPLICATION-ATTACK-LFI规则是为通用Web路径设计的,不区分管理后台语义。phpMyAdmin大量使用POST字段携带SQL片段:sql_query、where_clause、import_text,这些字段名固定、内容合法但含UNION、SELECT、..等关键字。CRS一旦在这些字段里匹配到正则模式,就直接返回403 Forbidden。
典型日志线索:Matched "Operator `Rx' with parameter `(?i:(?:%2f%2e%2e|%2e%2e%2f|.\.|./.)`' 或 SQL injection detected,而URI明确是/phpmyadmin/import.php或/phpmyadmin/sql.php。
- 不要用
SecRuleEngine Off关整个WAF——这等于裸奔 - 不要用
SecRuleRemoveById 942100全局禁用SQLi规则——会漏掉对其他路径的真实攻击 - 必须按路径+参数两级放行:先限定作用域为
/phpmyadmin,再跳过特定字段的检测
Apache下精准豁免的关键配置写法
在Apache主配置或虚拟主机块中,用<Location>而非<Directory>(后者不匹配alias或符号链接路径),严格对应你的访问入口(比如是/phpmyadmin还是/pma):
<Location "/phpmyadmin">
SecRuleRemoveById 930100 930110 942100 942150 942200
SecRuleUpdateTargetById 932100 !ARGS:token
SecRuleUpdateTargetById 942100 !ARGS:sql_query !ARGS:import_text !ARGS:where_clause
SecRuleUpdateTargetById 942150 !ARGS:sql_query !ARGS:import_text
</Location>说明:
立即学习“PHP免费学习笔记(深入)”;
-
930100/930110:LFI类规则,phpMyAdmin的import.php常带../路径字面量(如导入本地文件时的提示文本) -
942100/942150/942200:SQLi核心规则,只移除ID,不关闭整条规则链 -
!ARGS:token:跳过对CSRF token参数的校验,否则登录页提交后因token含base64编码被拦 -
!ARGS:sql_query等:明确告诉WAF“这个字段里出现SELECT是正常的,别扫”
Nginx下静态资源必须跳过规则引擎
ModSecurity若对/phpmyadmin/js/或/phpmyadmin/themes/下的JS/CSS做全量扫描,会因文件内正则字面量(如/(script)/i)或Base64字符串触发误报,导致界面白屏或按钮失效。
在Nginx配置中显式关闭这些路径的规则引擎:
location ~ ^/phpmyadmin/(js|css|images|themes)/ {
SecRuleEngine Off;
}同时确认SecRequestBodyAccess On仅作用于动态入口,例如:
location ~ ^/phpmyadmin/(index\.php|import\.php|sql\.php) {
SecRequestBodyAccess On;
include /etc/nginx/modsecurity.conf;
}否则WAF无法解析POST体里的sql_query字段,放行就失去意义。
XSS检测要分场景启用多层解码
phpMyAdmin自身对<script>有基础转义,但旧版本或插件可能漏掉<ScRiPt>、<img src=x onerror=alert(1)>或URL编码的%3Cscript%3E。WAF若只做单层匹配,容易绕过;若粗暴拦截所有onerror又会干掉管理员写的调试脚本。
实操要点:
- 启用
SecRule REQUEST_HEADERS:Content-Type "application/x-www-form-urlencoded" "id:1001,phase:1,pass,nolog,ctl:forceRequestBodyVariable=On"确保POST体被解析 - 在CRS配置中开启
crs-setup.conf里的SecAction "id:900110,phase:1,pass,nolog,ctl:ruleEngine=On"并确认tx.enforce_body_proc设为On - 禁止在GET请求中出现
on*、javascript:、data:——这些在phpMyAdmin的GET参数里毫无合法用途 - 允许
POST的sql_query字段含onerror字面量(因为SQL字符串里可能有ON DELETE CASCADE)
真正难处理的是混合编码XSS,比如%3Cscript%3Ealert%281%29%3C%2Fscript%3E再HTML实体编码成%3Cscript%3E。WAF必须开启多层解码检测,否则日志里只会看到一堆%,查不到原始payload。



















