apache 本身不内置 sql 注入检测能力,需依赖 mod_security(配合 owasp crs)或 mod_rewrite 在请求入口拦截;前者更全面可靠,后者轻量但仅限 get 参数;二者均为兜底防护,不可替代应用层预编译语句。

Apache 本身不内置 SQL 注入检测能力,但可通过 mod_security 模块(第三方 WAF)或 mod_rewrite 规则在请求入口做基础关键字拦截。这不是替代预编译的方案,而是多一层兜底防护,适合快速上线简易过滤。
启用 mod_rewrite 做 URL 参数级拦截
这是最轻量、无需额外模块的方式,适用于 Apache 2.4+。把规则加到站点配置(如 /etc/apache2/sites-enabled/your-site.conf)或 .htaccess 中:
- 只对 GET 请求的查询字符串(
QUERY_STRING)做匹配,避免误伤 POST 数据体 - 拦截常见 SQL 关键字和危险符号,如
union select、insert into、1=1、单引号后接空格或注释符 - 使用
R=403直接拒绝,不重定向,减少暴露路径风险
示例规则:
RewriteEngine On
RewriteCond %{QUERY_STRING} "(union\s+select|insert\s+into|drop\s+table|delete\s+from|update\s+set|exec(\s+|\()|xp_cmdshell)" [NC]
RewriteRule ^ - [F]
<p>RewriteCond %{QUERY_STRING} "(1\s<em>=\s</em>1|2\s<em>=\s</em>2|--|#|;|*|/*|*/)" [NC]
RewriteRule ^ - [F]</p><p>RewriteCond %{QUERY_STRING} "('|%27)\s*(and|or|xor|like|in|between)" [NC]
RewriteRule ^ - [F]
</p>
注意:正则要区分大小写敏感性([NC] 表示忽略大小写),且需启用 mod_rewrite(a2enmod rewrite)。
用 mod_security + OWASP CRS 快速启动
这是更可靠的基础防护方式。mod_security 是 Apache 的开源 Web 应用防火墙模块,配合 OWASP Core Rule Set(CRS)可自动识别 SQLi 模式。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 安装:
apt install libapache2-mod-security2(Debian/Ubuntu),然后复制默认配置:cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf - 启用 CRS 规则集:下载最新版 OWASP CRS(如 v4.x),解压后软链到
/etc/modsecurity/crs/,并在modsecurity.conf中取消注释Include /etc/modsecurity/crs/rules/*.conf - 关键开关设为
SecRuleEngine On(开发环境可先设为DetectionOnly观察日志)
CRS 默认包含数百条 SQL 注入规则,覆盖布尔盲注、报错注入、堆叠注入等常见变种,比手工正则更全面。
配合 PHP 层做参数级过滤(辅助手段)
Apache 层拦截是前置防线,但真正安全要落在应用层。可在 PHP 入口(如 index.php 开头)统一处理 GET/POST 参数:
- 对所有字符串型参数,用
str_ireplace()过滤掉select、union、exec等关键词(仅作应急,不能代替预编译) - 强制数字型参数调用
intval()或正则/^\d+$/校验 - 禁用
magic_quotes_gpc(已废弃),改用mysqli_real_escape_string()—— 但注意这只是逃生,不是根本解法
例如:
foreach ($_GET as $k => $v) {
if (is_string($v)) {
$v = str_ireplace(['union', 'select', 'insert', 'drop', 'exec'], '', $v);
$_GET[$k] = trim($v);
}
}
必须同步做的关键事项
Apache 层过滤只是补充,以下三点缺一不可:
- 所有数据库操作必须用预编译语句(
PreparedStatement、MyBatis 的#{}、PDO 的bindParam) - 关闭 PHP 的
display_errors和expose_php,防止错误信息泄露数据库结构 - 数据库账号最小权限原则:Web 应用账号只授予
SELECT/INSERT/UPDATE,禁用DROP/CREATE/GRANT










