核心是利用SecRule匹配恶意模式并结合解码归一化精准触发;必须开启SecRequestBodyAccess、配置t:urlDecodeUni/t:lowercase等转换函数,优先使用CRS并补充自定义规则,上线前需日志全开、先log后block、引入异常评分机制。

直接在 Apache 的 ModSecurity 中编写规则拦截 SQL 注入,核心是利用 SecRule 匹配请求中典型的恶意模式,并结合解码、归一化和上下文变量精准触发。不能只靠关键词黑名单硬拦,否则容易被大小写、URL 编码、注释分隔等手法绕过。
关键配置前提必须到位
规则生效的前提不是“写了就管用”,而是环境已正确初始化:
-
开启请求体解析:默认不读 POST body,必须显式设置
SecRequestBodyAccess On,否则表单提交的注入(如登录框输入admin' OR '1'='1)完全检测不到 -
启用解码与归一化:添加
SecResponseBodyAccess On(防错误信息泄露),并确保SecResponseBodyMimeType包含text/html;CRS 规则依赖urlDecodeUni、normalizePath等转换函数,别禁用 -
规则加载顺序要合理:基础清洗规则(如 REQUEST-901-INITIALIZATION.conf)必须在 SQLI 规则前加载,否则变量未初始化,
ARGS、REQUEST_COOKIES都为空
自定义SQL注入拦截规则写法(Apache + ModSecurity)
不建议从零手写全部规则,但可补充 CRS 漏检场景。以下为生产可用的精简示例,放在自定义规则文件(如 custom-sqli.conf)中:
# 拦截高危数字型注入(如 id=1 AND 1=1)SecRule ARGS "@rx \b(?:and|or|x?or|not)\b\s+\d+\s*=\s*\d+" "id:1001,phase:2,block,msg:'SQLi: Boolean-based number injection',tag:'OWASP_CRS',severity:2"
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
# 拦截常见变形字符型注入(含 URL 编码、空格绕过)SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES "@rx (?i:(?:'|\")\s*(?:or|and)\s+(?:'|\")\d+\s*(?:'|\")\s*=\s*(?:'|\")\d+(?:'|\")|union\s+all\s+select|select\s+.*?\s+from\s+\w+)" "id:1002,phase:2,block,msg:'SQLi: Classic union/select or quoted boolean',tag:'OWASP_CRS',t:urlDecodeUni,t:lowercase,severity:2"
# 拦截注释符滥用(--、#、/*)后接关键字SecRule ARGS "@rx (?:--|#|/\*)\s*(?:select|insert|update|delete|drop|exec|execute)\b" "id:1003,phase:2,block,msg:'SQLi: Comment-delimited SQL keyword',tag:'OWASP_CRS',t:urlDecodeUni,severity:2"
绕过常见、必须应对的点
攻击者不会老老实实输 union select,真实流量中这些变形极多:
-
双写/混写绕过:如
sel/**/ect、UNIunionON—— CRS v3.3+ 已支持归一化,但需确认tx.normalized_input变量被正确生成 -
编码嵌套:如
%2527(%27 的二次 URL 编码)—— 要求t:urlDecodeUni多次执行,ModSecurity 默认只解一次,需在规则中显式叠加t:urlDecodeUni -
空白符替换:用
%09(tab)、%0a(换行)、/**/替代空格 —— 正则中用\s+或[[:space:]]+匹配更稳妥
验证与调优不能跳过
上线前必须做三件事:
-
日志开全:设置
SecAuditLogRelevantStatus "^(?:4|5)."和SecAuditLogParts ABIJDEFHZ,重点看modsec_audit.log中Matched Data字段,确认是真命中还是误报 -
先 log 后 block:首次部署把
block改成log,pass,观察一周,尤其关注order by id、limit 10这类合法语句是否被误杀 -
异常分数联动:不要单条规则就 403,建议用 CRS 的异常评分机制:
SecRule TX:ANOMALY_SCORE "@gt 5" "id:99999,phase:2,deny,status:403,msg:'SQLi Anomaly Score Exceeded'",让多条低置信度规则协同判断

















