SQL注入漏洞自查,CMS网站防注入配置
SQL注入漏洞自查和CMS网站防注入配置,是很多站长在网站上线后必须补的一课。
如果你发现后台日志里出现大量带引号、union、select 的异常请求,或者安全扫描工具报了405类风险,说明站点可能正在被探测。
本文按零基础也能照做的顺序,讲清怎么查、怎么堵、怎么验证。
先判断漏洞是否真实存在
不要看到扫描器报红就直接改代码,先做两件事确认风险范围。
- 查看Web访问日志,筛选可疑参数。宝塔面板路径:
网站→设置→日志,或直接看/www/wwwlogs/你的域名.log。 - 用命令快速过滤高风险请求:
grep -Ei "union.*select|select.*from|information_schema|sleep\(|benchmark\(" /www/wwwlogs/你的域名.log | tail -50
如果日志里出现大量类似 ?、
id=1%27? 的请求,且返回状态码为200或500,就说明站点参数可能被带进了SQL查询。
id=1 and 1=1
另一个快速判断方法:在浏览器地址栏给某个带数字参数的页面加上单引号,例如 article.php?。
id=1'
如果页面报数据库错误,或者内容与正常访问明显不同,说明该参数没有做过滤。
结论:SQL注入自查的第一步不是改代码,而是通过日志和参数测试确认哪些入口可被利用。
CMS代码层的排查重点
不同CMS的文件结构不同,但注入点通常集中在几类文件里。
- 搜索功能:
search.php、search.php?keyword= - 列表分页:
list.php?page=、category.php?id= - 文章详情:
show.php?id=、article.php?aid= - 用户登录:
login.php、admin/login.php
打开这些文件,重点看SQL语句是否直接拼接了 $_GET、$_POST、$_REQUEST 变量。
例如下面这种写法风险很高:
$id = $_GET['id'];
$sql = "SELECT * FROM articles WHERE id = $id";
正确的做法是使用预处理语句,或者至少做整数强制转换:
$id = intval($_GET['id']);
$sql = "SELECT * FROM articles WHERE id = ?";
如果你不熟悉代码修改,优先检查CMS是否有官方安全补丁。
很多老版本CMS的注入漏洞已经在后续版本中修复,升级往往比手动改代码更稳妥。
Nginx层拦截常见注入请求
在代码修复之前,可以先在Nginx配置里加一层规则,拦截明显的注入尝试。
宝塔面板路径:网站 → 设置 → 配置文件。
在 server {} 块内加入:
if ($request_uri ~* "(union.*select|select.*from|information_schema|sleep\(|benchmark\(|load_file\()") {
return 403;
}
if ($query_string ~* "(\%27|\'|\") {
return 403;
}
保存后重载Nginx:
nginx -t && nginx -s reload
这条规则会直接拒绝包含典型注入关键词的请求。注意:Nginx规则只能拦截明显攻击,不能替代代码层的参数过滤。 如果攻击者使用编码变形,仍可能绕过。
PHP与数据库层的加固配置
PHP层面可以做两件低成本但有效的事。
第一,关闭错误回显,避免数据库报错泄露表结构。
编辑 php.ini,设置:
display_errors = Off
log_errors = On
宝塔面板中可在 软件商店 → PHP → 设置 → 配置修改 里操作,改完重启PHP。
第二,检查数据库账号权限。
不要给网站数据库账号授予 FILE、SUPER 等高危权限。
在MySQL中执行:
SHOW GRANTS FOR '网站数据库用户'@'localhost';
如果看到 GRANT ALL PRIVILEGES,建议收回多余权限,只保留 SELECT, INSERT, UPDATE, DELETE 等必要权限。
判断条件:如果数据库账号只有业务所需的最小权限,即使注入点被利用,攻击者能做的事情也会大幅减少。
验证防注入配置是否生效
改完配置后,不要只看规则有没有写进去,要实际测试。
- 访问正常页面,确认网站功能没有误伤。
- 在参数后加单引号,例如
article.php?id=1',观察是否返回403或正常错误页。 - 查看Nginx日志,确认拦截记录:
tail -f /www/wwwlogs/你的域名.log | grep 403
- 用安全扫描工具对站点做一次复测,对比修复前后的报告差异。
如果正常访问也被拦截,优先检查Nginx规则里的正则是否过于宽泛,比如把普通搜索词也匹配进去了。
调整后再次 nginx -t 测试配置。
几个容易踩的坑
- 只加Nginx规则不改代码,遇到编码绕过仍然会中招。
- 直接在生产环境改代码不备份,出问题后无法快速回滚。
- 忽略CMS官方补丁,老版本漏洞反复被利用。
- 数据库账号权限过大,注入成功后攻击者可以直接读写文件。
建议:每次修改配置前先备份原文件,改完后用 nginx -t 或PHP配置检查命令验证语法。
常见疑问
问:加了Nginx规则后,网站搜索功能返回403怎么办?
答:检查规则中的正则是否匹配了正常搜索关键词,适当缩小匹配范围,或者只对特定参数做拦截。
问:CMS没有官方补丁,还能怎么防?
答:可以在入口文件统一过滤参数,使用 intval() 处理数字型参数,对字符串型参数使用 mysqli_real_escape_string() 转义,并限制数据库账号权限。
问:怎么确认注入漏洞已经被修复?
答:复现之前的注入测试请求,观察是否被拦截或返回正常错误页;同时检查数据库账号权限和错误日志,确认没有异常查询记录。
SQL注入漏洞自查和CMS网站防注入配置不是一次性的工作。
上线前做一次排查,上线后定期看日志和更新CMS版本,才能把风险控制在可接受范围内。
如果你正在处理405类风险提示,建议先按本文步骤完整执行,再根据自己的环境微调规则。