PHP网站被SQL注入写入webshell排查_从原理到修复_测试方法_开发者指南
SQL注入是PHP网站最常见的安全漏洞之一,也是危害最严重的漏洞之一。攻击者通过在URL参数、表单输入、Cookie等位置插入恶意SQL语句,可以绕过登录验证、窃取数据库内容、修改或删除数据,甚至通过SQL注入写入webshell获取服务器控制权。很多PHP程序因为开发时没有重视安全,存在大量SQL注入漏洞,被安全扫描工具报出后不知道如何修复。本文讲解PHP程序SQL注入漏洞的检测、修复、验证全流程。
白盒检测是通过代码审计找出SQL注入漏洞。审计方法:搜索代码中所有执行SQL查询的函数,如mysql_query、mysqli_query、PDO::query、$wpdb->query、$db->query等。检查这些函数中的SQL语句是否拼接了用户输入($_GET、$_POST、$_COOKIE、$_REQUEST、$_SERVER等变量)。如果SQL语句中直接拼接了用户输入且没有使用参数化查询,就是潜在的注入点。重点关注WHERE条件、ORDER BY、LIMIT、表名、列名等位置的拼接,这些都是常见的注入点。代码审计能发现黑盒检测无法发现的漏洞,是最全面的检测方法。
SQL注入漏洞的检测分为黑盒检测和白盒检测。黑盒检测是在不查看源码的情况下,通过构造特殊输入测试是否存在注入。检测方法:在URL参数后添加单引号',如果页面报错或显示异常,可能存在注入。添加AND 1=1和AND 1=2,如果两个请求的页面内容不同,说明存在数字型注入。添加' OR '1'='1,如果返回了不应有的数据,说明存在字符型注入。使用专业扫描工具(如SQLMap、AWVS、Nessus)进行自动化扫描,这些工具能检测出各种类型的SQL注入,包括盲注。扫描时注意不要在生产环境进行大规模扫描,避免影响网站性能。
对于无法使用参数化查询的场景(如ORDER BY、表名、列名),需要使用白名单验证。ORDER BY注入是常见的注入点,因为ORDER BY后面的参数不能用预处理占位符。修复方法:定义允许的排序字段白名单,如$allowed = ['id', 'name', 'date']; $order = in_array($_GET['order'], $allowed) ? $_GET['order'] : 'id';。表名和列名同样使用白名单验证,不要直接使用用户输入。对于LIKE查询中的搜索参数,可以使用预处理,但需要注意转义%和_通配符:$search = str_replace(['%', '_'], ['%', '_'], $_GET['search']); $stmt = $pdo->prepare('SELECT * FROM articles WHERE title LIKE ?'); $stmt->execute(['%' . $search . '%']);
MySQLi预处理的使用方法:$mysqli = new mysqli('localhost', 'user', 'pass', 'test'); $stmt = $mysqli->prepare('SELECT * FROM users WHERE id = ?'); $stmt->bind_param('i', $_GET['id']); $stmt->execute(); $result = $stmt->get_result();。bind_param的第一个参数是类型字符串,i表示整数,s表示字符串,d表示浮点数,b表示二进制。使用MySQLi预处理时,确保设置了正确的字符集:$mysqli->set_charset('utf8')。MySQLi预处理默认使用原生预处理,不存在模拟预处理的问题,安全性更高。
防止SQL注入的开发规范。第一,永远不要信任用户输入,所有来自客户端的数据(GET、POST、Cookie、HTTP头、上传文件名)都视为不可信。第二,所有SQL查询使用参数化查询,禁止直接拼接用户输入到SQL语句中。第三,使用最新的PHP数据库扩展(PDO或MySQLi),不要使用已废弃的mysql_*函数。第四,设置正确的数据库字符集,使用utf8或utf8mb4,避免宽字节注入。第五,数据库用户使用最小权限,只授予必要的权限,不要使用root或管理员账户连接网站。第六,关闭PHP的display_errors,生产环境不显示错误信息,避免错误信息泄露数据库结构。第七,定期进行代码审计和安全扫描,及时发现和修复新的注入漏洞。
运维案例:一个客户的PHP网站被SQL注入,数据库中的用户密码被下载。处理时不仅修复了注入漏洞,还检查了数据库发现攻击者创建了一个隐藏的管理员账户。删除了后门账户,强制所有用户修改密码,同时部署了WAF。后续虽然仍然有注入尝试,但都被WAF拦截。
修复提醒:修复SQL注入漏洞时,不要只修复被扫描工具检测到的注入点,要进行全面的代码审计,检查所有SQL查询。扫描工具可能有遗漏,只有全面审计才能确保没有注入点。修复后进行充分的测试,确认功能正常且漏洞已修复。

更新时间:2026-08-27 12:05:01