SQL注入告警出现时应立即阻断可疑IP而非重启服务,因payload已触达数据库层;需在Nginx或云防火墙封禁高频注入特征,优先封X-Forwarded-For中的CIDR段,并通过数据库慢查询日志定位高危接口,再以入口参数校验快速修复。

SQL注入告警一出现,先别重启服务,立刻冻结可疑IP
告警不是提示“可能有风险”,而是说明已经有恶意 payload 触达数据库层。这时候最有效的第一动作是阻断请求源头,而不是查日志或改代码。
常见错误现象:SELECT * FROM users WHERE id = '1' OR '1'='1' 这类 payload 已在 WAF 或数据库审计日志里出现,但应用层还没报错——说明攻击已绕过部分校验,正在试探。
- 立即在 Nginx 或云防火墙配置临时规则,
deny匹配UNION SELECT、OR 1=1、AND SLEEP(等高频注入特征的User-Agent或query string - 如果用的是阿里云 WAF 或腾讯云 Web 应用防火墙,直接在控制台启用「SQL注入攻击自动封禁」策略,阈值设为 1 次/5 分钟(别用默认的 5 次,太迟)
- 不要只封单个 IP:攻击者常走代理池,优先封
X-Forwarded-For头里反复出现的 CIDR 段,比如192.168.34.0/24
快速定位被攻破的接口:从数据库慢查询日志反推
SQL 注入不一定报错,但一定会产生异常查询模式。比看应用日志更可靠的是直接翻数据库的 slow_query_log 或 general_log。
使用场景:告警没带具体 URL,只知道 DB 出现了非预期的 SELECT ... FROM information_schema 或大量 ORDER BY RAND() 查询。
- MySQL 开启方式:
SET GLOBAL slow_query_log = ON;SET GLOBAL long_query_time = 0.1(把阈值压到 100ms,方便捕获短平快注入) - 重点 grep:
mysqldumpslow -s t /var/lib/mysql/slow.log | grep -E "(union|information_schema|sleep|benchmark)" - 查出后立刻对应到应用代码里的
query变量:不是所有拼接都用format,有些框架用raw方法或db.query直接透传字符串,这些才是高危点
应急修复不改业务逻辑,只加参数化约束
上线前没做预编译?现在不能重写 DAO 层。要选影响最小、见效最快的补救方式——在入口强制类型/长度/字符集校验,把恶意 payload 拦在 SQL 构造之前。
参数差异:id=1 和 id=1%20OR%201=1 在路由层看起来都是字符串,但业务上 id 必须是正整数,那就用最硬的规则卡死。
- Node.js Express:在路由 handler 前加中间件,对
req.query.id执行parseInt(req.query.id, 10) === NaN || req.query.id.includes(' '),直接res.status(400).end() - Python Flask:
if not re.match(r'^d+$', request.args.get('id', '')):,别用int()尝试转换再 try-except,性能差且可能被绕过 - Java Spring:
@Pattern(regexp = "\d+", message = "invalid id") String id配合@Valid,比在 service 层做Long.parseLong更早拦截
为什么 WAF 规则不能代替代码修复
WAF 是漏斗,不是保险柜。它能拦住典型 payload,但对编码绕过(如 %2527 是 ' 的双重 URL 编码)、注释符变形(/*!*/)、或利用 JSON 接口的 WHERE IN (?) 注入完全无效。
性能影响:开全量 SQL 注入规则会导致平均 RT 上升 8–12ms(实测 Nginx+ModSecurity),而应用层校验是纳秒级的。
- 某次真实事件:WAF 拦住了
UNION SELECT,但攻击者切到UPDATE users SET password='xxx' WHERE id=1#,因 # 被 WAF 当作注释忽略,成功改密 - 兼容性坑:PostgreSQL 的
||字符串拼接、SQLite 的PRAGMA指令,很多 WAF 规则库压根没覆盖 - 真正可靠的防线永远在参数进入
db.query前那一刻——那里没有“差不多”,只有“要么是数字,要么拒掉”
复杂点在于,同一个参数在不同接口语义不同:比如 name 在搜索页允许模糊匹配,在导出页却必须限制为 ASCII 字母+下划线。应急时容易一刀切,结果把正常功能干掉了。

















