35 lines
2.6 KiB
Markdown
35 lines
2.6 KiB
Markdown
### 文件上传防御方法
|
||
|
||
**1. 客户端验证**
|
||
|
||
客户端验证通常指通过 JavaScript 在前端对文件进行检查
|
||
|
||
- **优点**:可以快速、友好地提示用户,减少不必要的服务器请求,提升用户体验
|
||
- **缺点**:非常容易绕过。攻击者可以通过抓包工具(如 Burp Suite)修改 HTTP 请求,或直接禁用 JavaScript。因此,**客户端验证绝对不能作为唯一的安全措施**
|
||
|
||
常见的客户端验证包括:
|
||
|
||
- **文件扩展名验证**:检查文件的扩展名是否为允许的类型(如`.jpg`, `.png`, `.pdf`)
|
||
- **MIME类型验证**:检查文件的 MIME 类型(如 `image/jpeg`, `application/pdf`)
|
||
- **文件大小验证**:限制上传文件的大小,防止恶意文件过大导致服务器资源耗尽
|
||
|
||
**2. 服务器端验证**
|
||
|
||
服务器端验证是防御文件上传漏洞的最后一道防线,也是最可靠的
|
||
|
||
- **文件扩展名白名单验证**:**强烈推荐使用白名单**。只允许上传特定、已知的安全扩展名,如 `.jpg`, `.png`, `.gif`, `.pdf`, `.zip` 等。**绝对不要使用黑名单**,因为攻击者总能找到新的绕过方式
|
||
- **MIME 类型验证**:在服务器端验证文件头的 MIME 类型,防止攻击者通过伪造扩展名来上传恶意文件
|
||
- **文件内容检测**:对上传的文件内容进行深度检查
|
||
- **图片**:使用 `getimagesize()` 等函数检测文件是否为真实的图片文件
|
||
- **压缩包**:检查压缩包中的文件列表,确保没有可执行文件或恶意脚本
|
||
- **文件重命名**:在文件上传后,对其进行重命名,通常是使用一个随机字符串或加密哈希值作为文件名,并去除原始扩展名。这能有效防止攻击者通过文件名猜测 WebShell 的路径
|
||
|
||
**3. 文件存储与执行权限控制**
|
||
|
||
即使恶意文件侥幸通过了所有验证,我们仍然可以通过权限控制来阻止它被执行。
|
||
|
||
- **分离存储与执行**:将用户上传的文件存储在**非Web根目录**下。这样,即使攻击者知道文件路径,也无法通过URL直接访问或执行。
|
||
- **禁止执行权限**:将上传文件的目录设置为**不可执行**。在Nginx或Apache中,可以通过配置来禁止特定目录执行脚本文件。
|
||
- **Nginx**:在配置文件中添加 `location` 规则,并设置 `deny all;` 或 `deny execution;`。
|
||
- **Apache**:在 `.htaccess` 文件中添加 `php_flag engine off` 或类似的规则。
|
||
- **最小权限原则**:Web服务器进程(如Nginx、Apache)应以低权限用户运行,并确保其对上传目录只有**写入**权限,而**没有执行**权限。 |