PHP强制下载文件代码防PHP2Shell上传执行
通过设置正确的http响应头(content-disposition: attachment)并配合严格的白名单校验,可以强制浏览器下载文件而非直接执行,从而有效防止php2shell等恶意脚本利用上传功能在服务器上执行。具体做法是在处理上传或文件访问的php脚本中,先验证文件名是否在允许列表中,然后输出二进制流并附加下载头,确保用户端行为为保存而非渲染。

如何配置Content-Disposition头实现强制下载
将Content-Type设置为application/octet-stream并将Content-Disposition设为attachment; filename="..."是强制下载的关键。这告诉浏览器不要尝试预览内容,而是启动下载对话框。结合输入过滤,可阻断攻击者通过修改MIME类型或利用解析漏洞执行上传的PHP文件。

<?php // 示例:安全下载文件
$allowed_files = ['readme.txt', 'data.csv'];
$file = $_GET['file'] ?? '';
if (!in_array($file, $allowed_files)) {
http_response_code(403);
die('Access denied');
}
$path = '/var/www/files/' . basename($file); // 防止目录穿越
if (file_exists($path)) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file . '"');
header('Content-Length: ' . filesize($path));
readfile($path);
exit;
}
?>
预期结果:当请求?file=readme.txt时,浏览器弹出保存对话框;若请求?file=shell.php且不在白名单中,则返回403错误,无法执行任何代码。
基于程序中某个输入、条件或结果的具体问题
在上述代码中,如果$file参数包含路径遍历字符如../../etc/passwd,即使经过basename()处理,仍需确保基础路径不可变。此外,若未正确设置Content-Type,某些浏览器可能仍会尝试执行上传的PHP文件,导致安全风险。因此,必须严格限制可访问的文件扩展名,并始终使用application/octet-stream作为默认类型。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











