PHP过滤数据防止文件上传漏洞

简介:本文介绍了PHP文件上传漏洞的危害,包括允许攻击者上传webshell控制网站。通过示例展示了不安全的文件上传代码,并提出了通过检查文件类型和扩展名来防止漏洞的方法。然而,仅依赖MIME类型和扩展名检查并不足够,还存在Apache扩展名解析漏洞。为了增强安全性,建议结合使用随机文件名、存储在非执行目录以及设置上传目录为静态资源。同时,部署时应确保上传目录无执行权限

在PHP项目中, 提供上传功能并在服务器端未对上传的文件格式进行合理的校验是存在巨大风险的。如果恶意攻击者利用上传漏洞上传一些 webshell,则可能完全控制整个网站程序, 执行系统命令(如删除系统文件), 获取数据库连接字符串进行数据库操作等危险操作。

造成漏洞的原因有以下几点:

  1. 前端校验不严格:前端校验容易被绕过,攻击者可以通过工具如BurpSuite拦截并修改请求包。
  2. 后端校验不足:后端未对上传文件的类型、内容进行严格检查。
  3. 中间件解析漏洞:如Apache、Nginx等中间件存在解析漏洞,可能导致文件被错误解析为PHP脚本。
  4. 配置不当:服务器配置不当,如开启了不安全的文件类型解析

下面我们结束一下PHP后的解决漏洞的方法:

1. 验证文件类型

攻击者可能会将.txt文件重命名为.php文件(还有可能上传webshell文件执行cmd命令提取系统相关信息),并上传到服务器上,然后通过直接访问该文件来执行恶意代码。为了防止这种情况发生,我们需要验证用户上传的文件类型,确保它是我们期望的类型。

下面是一个简单的代码示例,用于验证文件类型:

function checkFileType($file)
{
    $allowedTypes = array('image/jpeg', 'image/png', 'image/gif');
    
    if (in_array($file['type'], $allowedTypes)) {
        return true;
    }
    
    return false;
}

// 检查上传的文件
checkFileType($_FILES['file'])

2. 检查文件大小

攻击者可能会上传过大的文件,从而导致服务器存储空间耗尽或系统崩溃。我们应该限制用户上传的文件大小,并对其进行检查。

下面是一个简单的代码示例,用于检查文件大小:

function checkFileSize($file)
{
    $maxSize = 1024 * 1024; // 限制文件大小为1MB
    
    if ($file['size'] <= $maxSize) {
        return true;
    }
    
    return false;
}

// 检查上传的文件
checkFileType($_FILES['file'])

3. 防止文件上传漏洞

除了验证文件类型和文件大小外,我们还需要防止文件上传漏洞。攻击者可能会通过上传包含恶意代码的文件来执行任意代码。为了防止这种情况发生,我们可以使用以下方法:

将上传的文件保存在非Web可访问的目录中,这样就可以防止攻击者直接访问上传的文件;使用随机生成的文件名和独特的文件路径,避免恶意脚本直接访问上传的文件;设置适当的文件权限,确保上传的文件不可执行。下面是一个简单的代码示例,用于实现上述方法:

function saveUploadedFile($file)
{
    $uploadDir = '/path/to/uploads/';
    $filename = uniqid() . '_' . $file['name'];
    $targetFile = $uploadDir . $filename;
    
    // 将上传的文件移动到指定目录
    if (move_uploaded_file($file['tmp_name'], $targetFile)) {
        // 文件保存成功,继续处理
    } else {
        // 文件保存失败,抛出错误或进行其他操作
    }
}

// 检查上传的文件
checkFileType($_FILES['file'])
虽然这些方法在一定程度上可以规避漏洞,但是对于资深黑客可能还是不够。最好是将图片单独部署到一台服务器上或者上传的oss云上,这样即使有漏洞黑客也只能获取图片服务器的信息,不会影响到正常服务器的运营,更不会泄露用户等信息

如果我们使用了框架,可以利用框架内置的验证来过滤文件。以tp6框架为例,tp框架提供是否上传文件,文件类型,文件后缀等一系列的验证,具体验证代码如下:

namespace app\validate;

use think\Validate;

class User extends Validate
{
    protected $rule = [
        'avatar'  =>  'require|file|image:300,300,jpg|fileExt:jpg|fileMime:image',
        'email' =>  'email',
    ];

}

上述验证类针对avatar验证是否上传头像文件,并且宽高为300,格式为jpg的图片

总结

通过对用户上传文件进行严格的过滤和检查,我们可以有效地防止文件上传漏洞。验证文件类型、文件大小和防止文件上传漏洞是保护Web应用程序安全的重要步骤。同时,我们还应该保持代码的更新和加强安全意识,以确保Web应用程序的持续安全性。

有什么不对的可以在我的公众号留言

编程经验共享公众号二维码

编程经验共享公众号二维码
更多内容关注公众号
Copyright © 2021 编程经验共享 赣ICP备2021010401号-1