在带有文件上传功能的网站中,如果上传目录直接位于 Web 根目录下,且未做访问限制,任何知道文件 URL 的人都能通过浏览器直接下载该文件。这种直接 URL 访问会让身份证照片、合同 PDF 等敏感资料泄露。防止此类问题需要从服务器配置、应用鉴权和存储位置几方面入手。

为什么直接 URL 能访问文件
当文件被保存到如 uploads/ 这种可通过 HTTP 访问的目录时,Web 服务器默认会像处理普通静态资源一样把文件返回给请求者。只要 URL 格式正确,不需要登录也能拿到内容。
常见防护方案
1. 将文件放在 Web 根目录之外
把上传文件存到程序可读取但 Web 服务器不对外服务的路径,例如 /var/internal_uploads/,再通过后端脚本做权限判断后输出文件。
<?php
// 用户请求 download.php?file=abc.jpg
session_start();
if (!isset($_SESSION['user_id'])) {
http_response_code(403);
exit('无权限');
}
$file = '/var/internal_uploads/' . basename($_GET['file']);
if (file_exists($file)) {
header('Content-Type: image/jpeg');
readfile($file);
}
?>
2. 用 Web 服务器规则拒绝访问
如果文件必须在 Web 目录内,可以用服务器配置禁止直接访问。下面为 Nginx 示例,禁止 uploads/ 被公开读取。
location /uploads/ {
# 先判断是否有后端鉴权逻辑,这里直接拒绝
deny all;
return 403;
}
3. 程序层做鉴权中转
不要在前端直接写文件真实地址,而是提供类似 /file/get?id=123 的接口,由程序验证用户身份与权限后再读取并返回文件内容。
| 方案 | 适用场景 | 实现难度 |
|---|---|---|
| 目录外存储 | 新项目、可改路径 | 低 |
| 服务器规则 | 遗留系统快速堵漏 | 低 |
| 程序鉴权 | 需细粒度权限 | 中 |
注意事项
- 不要用文件名作为唯一凭证,别人可遍历。
- 输出文件时设置正确的 Content-Type 与下载头。
- 对
basename()等函数做过滤,防目录穿越。
敏感文件防护的核心是:让 Web 服务器不直接提供文件,或提供前必须经过可信程序检查。
按照上述思路组合使用,就能有效防止用户通过直接 URL 访问敏感上传文件。
file_upload_securityaccess_controlweb_server_config修改时间:2026-07-30 20:36:20