必须开启 SecRuleEngine On 并加载 OWASP CRS,否则规则完全不生效;需确认 mod_security 模块已加载、SecRequestBodyAccess On 已启用、crs-setup.conf 在所有规则前被包含,且审计日志与误报降权已配置到位。

必须开启 SecRuleEngine On 并加载 OWASP CRS,否则规则写得再全也完全不生效。
确认 mod_security 模块已加载且引擎启用
很多“配置完没反应”的问题,根源是模块根本没跑起来。先验证:
- 运行
apache2ctl -M | grep security(Ubuntu/Debian)或httpd -M | grep security(RHEL/CentOS),输出中必须含security2_module - 检查
/etc/modsecurity/modsecurity.conf中SecRuleEngine值为On,不是DetectionOnly或注释掉 - 确保
Include语句已加载 CRS 规则,例如:Include /usr/share/modsecurity-crs/rules/*.conf;且crs-setup.conf必须在所有规则前被包含(它初始化tx变量和评分机制)
关键参数必须显式开启:否则 POST 注入直接漏掉
CRS 默认只扫描 URI 和请求头,表单提交的 SQLi(如 login.php?user=admin' OR '1'='1 是 GET,但 POST /login 带 password=123'-- 就进不来)——原因就是没开请求体解析。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
-
SecRequestBodyAccess On:强制读取 POST body,让ARGS、REQUEST_BODY可用 -
SecResponseBodyAccess On:配合SecResponseBodyMimeType text/html,防止错误页面泄露数据库结构(如 MySQL 报错里的mysql_fetch_array) -
SecResponseBodyLimit 5242880(5MB):避免大响应体被截断导致规则匹配失败
绕过检测的常见 Payload 类型与对应防护要点
攻击者不会老老实实打 SELECT * FROM users,而是用大小写、编码、空格、注释分隔等手法绕过。CRS v3.3+ 支持归一化,但需确认转换链生效:
- URL 编码绕过(
sel%65ct)→ 必须在规则里加t:urlDecodeUni,t:lowercase,不能只依赖全局设置 - 注释分隔(
UNION/*abc*/SELECT)→ CRS 的REQUEST-942-APPLICATION-ATTACK-SQLI.conf已覆盖,但需确保t:removeComments在转换链中启用 - 空格替换(
/**/or/**/'1'='1)→ 规则中应使用@rx正则并搭配t:normalizePath或t:removeWhitespace预处理 - 注意:别禁用
SecUnicodeMapFile和SecUnicodeCodePage,否则 Unicode 编码载荷(如%u0061%u0064%u006D%u0069%u006E)无法解码
上线前必须做的三件事:日志、放行、验证
直接 SecRuleEngine On 上生产等于埋雷。真实环境里,搜索框带单引号、API 返回 JSON 含 "query": "SELECT" 都会触发误报。
- 先开全量审计日志:
SecAuditLogParts ABIJDEFHZ+SecAuditLog /var/log/apache2/modsec_audit.log - 对已知安全接口降权,例如:
SecRule REQUEST_URI "@beginsWith /api/v1/search" "id:1005,phase:1,pass,nolog,ctl:ruleRemoveByTag=OWASP_CRS" - 用真实 Payload 验证拦截效果:
curl "http://localhost/login?user=admin' OR 1=1--",然后查error.log是否有ModSecurity: Access denied,且返回状态码是403
最常被忽略的是 crs-setup.conf 加载顺序和 SecRequestBodyAccess On —— 这两个点没到位,其余所有规则都是摆设。

















