随着互联网的发展,基于PHP的网站仍然占据大量应用场景。由于PHP的灵活性与普及性,不安全的写法容易被攻击者利用。本文以实战角度介绍几类常见漏洞的利用方式与防御思路,并保留示例代码以便理解与修复(代码块尽量保持原样,仅清理了混乱的HTML结构)。文中已去除与站点推广或内部链接相关的信息。
描述:攻击者通过把恶意SQL片段注入到输入中,改变原有查询逻辑,从而绕过验证或窃取/篡改数据。
<?php
$id = $_GET['id'];
// 拼接 SQL 查询语句
$sql = "SELECT * FROM users WHERE id = " . $id;
// 执行查询
$result = mysqli_query($conn, $sql);
// 处理查询结果
// ...
?>
问题点:直接拼接用户输入会导致语句被篡改,比如传入 id=1 OR 1=1 将使条件恒为真,可能导致敏感数据泄露或认证绕过。
防护建议:使用参数化查询(预处理语句)或ORM,避免直接拼接用户输入;对输入进行类型校验(例如确保id为整数);对错误信息进行适当处理以免泄露内部细节。
描述:未对包含文件的路径进行严格控制时,攻击者可以通过传入特制路径包含任意文件,甚至远程文件(若配置允许),导致敏感文件泄露或远程代码执行。
<?php
$page = $_GET['page'];
// 拼接文件路径并包含文件
include("pages/" . $page . ".php");
?>
问题点:对 page 参数未做限制,攻击者可以通过类似 page=../config 的路径访问上级目录的敏感配置,或使用文件上传后的脚本进行执行。
防护建议:不要直接包含来自用户的路径;采用白名单机制限定可包含的文件名称;使用基底目录并在包含前将路径解析为绝对路径并验证其是否位于允许范围内;关闭允许远程包含的PHP配置选项(例如 allow_url_include)。
描述:文件上传功能若只检查文件扩展名或名称,攻击者可能上载伪装的可执行脚本并在服务器上执行,从而获取更高权限。
<?php
$targetDir = "uploads/";
$targetFile = $targetDir . basename($_FILES["fileToUpload"]["name"]);
// 检查文件类型
$fileType = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION));
if ($fileType != "jpg" && $fileType != "png" && $fileType != "jpeg" && $fileType != "gif") {
exit("只允许上传图片文件!");
}
// 上传文件
if(move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $targetFile)) {
echo "文件上传成功!";
} else {
echo "文件上传失败!";
}
?>
问题点:仅根据文件扩展名判断不可靠,攻击者可以改变扩展名或伪造MIME类型上传恶意脚本。
防护建议:
安全不是一次操作能够完成的,建议在开发与运维过程中采纳以下实践:
本文展示了几类典型的PHP安全问题及其防护思路。希望开发者能把安全意识贯穿于需求、设计、实现和运维的每个环节。对于示例中的每一类漏洞,实际环境可能更复杂,建议结合代码审计、自动化扫描与渗透测试结果进行有针对性的修复。