在 php 和 htaccess 中上传图像的安全方法

2024-01-21

我在互联网上找到了以下代码,用于在 php 中安全上传图像。

我想知道它涵盖了图像上传中所有可能的攻击方式。

define('MAX_SIZE_EXCEDED', 101);
define('UPLOAD_FAILED', 102);
define('NO_UPLOAD', 103);
define('NOT_IMAGE', 104);
define('INVALID_IMAGE', 105);
define('NONEXISTANT_PATH', 106);

class ImgUploader
{
  var $tmp_name;
  var $name;
  var $size;
  var $type;
  var $error;
  var $width_orig;
  var $height_orig;
  var $num_type;
  var $errorCode = 0;
    var $allow_types = array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG);

  function __construct($fileArray)
  {
    foreach($fileArray as $key => $value)
    {
      $this->$key = $value;
    }
    if($this->error > 0)
    {
      switch ($this->error)
      {
        case 1: $this->errorCode = MAX_SIZE_EXCEDED; break;
        case 2: $this->errorCode = MAX_SIZE_EXCEDED; break;
        case 3: $this->errorCode = UPLOAD_FAILED; break;
        case 4: $this->errorCode = NO_UPLOAD; break;
      }
    }
    if($this->errorCode == 0)
    {
      $this->secure();
    }
  }

  function secure()
  {
    //$this->num_type = exif_imagetype($this->tmp_name);
    @list($this->width_orig, $this->height_orig, $this->num_type) = getimagesize($this->tmp_name);

    if(filesize($this->tmp_name) > 1024*1024*1024*5) // allows for five megabytes.  Change this number if need be.
    {
      $this->errorCode = MAX_SIZE_EXCEDED;
      return false;
    }

    if (!$this->num_type)
    {
      $this->errorCode = NOT_IMAGE;
        return false;
    }
    if(!in_array($this->num_type, $this->allow_types))
    {
      $this->errorCode = INVALID_IMAGE;
      return false;
    }
  }

  function getError()
  {
    return $this->errorCode;
  }

  function upload_unscaled($folder, $name)
  {
    return $this->upload($folder, $name, "0", "0");
  }

  function upload($folder, $name, $width, $height, $scaleUp = false)
  {
    // $folder is location to be saved
    // $name is name of file, without file extention
    // $width is desired max width
    // $height is desired max height

    if($this->errorCode > 0)
      return false;

    // deal with sizing
    // if image is small enough to not scale, or upload_unscaled() is called, don't scale
    if((!$scaleUp && ($width > $this->width_orig && $height > $this->height_orig)) || ($width === "0" && $height === "0"))
    {
      $width = $this->width_orig;
      $height = $this->height_orig;
    }
    else
    {
      // if height diff is less than width dif, calc height
      if(($this->height_orig - $height) <= ($this->width_orig - $width))
        $height = ($width / $this->width_orig) * $this->height_orig;
      else
        $width = ($height / $this->height_orig) * $this->width_orig;
    }

    // Resample
    switch($this->num_type)
    {
      case IMAGETYPE_GIF: $image_o = imagecreatefromgif($this->tmp_name); $ext = '.gif'; break;
      case IMAGETYPE_JPEG: $image_o = imagecreatefromjpeg($this->tmp_name); $ext = '.jpg'; break;
      case IMAGETYPE_PNG: $image_o = imagecreatefrompng($this->tmp_name); $ext = '.png'; break;
    }

    $filepath = $folder.(substr($folder,-1) != '/' ? '/' : '');
    if(is_dir($_SERVER['DOCUMENT_ROOT'].$filepath))
      $filepath .= $name.$ext;
    else
    {
      $this->errorCode = NONEXISTANT_PATH;
      imagedestroy($image_o);
      return false;
    }

    $image_r = imagecreatetruecolor($width, $height);
    imagecopyresampled($image_r, $image_o, 0, 0, 0, 0, $width, $height, $this->width_orig, $this->height_orig);

    switch($this->num_type)
    {
      case IMAGETYPE_GIF: imagegif($image_r, $_SERVER['DOCUMENT_ROOT'].$filepath); break;
      case IMAGETYPE_JPEG: imagejpeg($image_r, $_SERVER['DOCUMENT_ROOT'].$filepath); break;
      case IMAGETYPE_PNG: imagepng($image_r, $_SERVER['DOCUMENT_ROOT'].$filepath); break;
    }

    imagedestroy($image_o);
    imagedestroy($image_r);

    return '/'.$filepath;
  }
}

我还有一个 .htaccess 文件存储在“images”文件夹中,该文件会关闭文件脚本,因此没有人可以执行 photos 文件夹中的脚本。

<Files ^(*.jpg)>
order deny,allow
deny from all
</Files>
Options -Indexes
Options -ExecCGI 
AddHandler cgi-script .php .php3 .php4 .php5 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi

出于安全原因,这是否足够,或者我必须采取其他一些步骤来保护我的代码和网站。


我要说的第一件事是检查文件类型与阿帕奇的mod_mime,否则我可以发送一个 HTTP 请求,其中显示我是一个JPEG文件!你只需信任文件扩展名,例如是的!你的扩展名为 .jpg,但实际上我可以注入PHP源代码而不是JPEG数据,然后我可以在你的服务器上执行PHP源代码。

另一件事是始终强制 Apache 不运行任何这些图像类型。你可以这样做力型指令。

<FilesMatch "(?i)\.jpe?g$">
    ForceType image/jpeg
</FilesMatch>

Edit:

我没有看到底线。关闭文件脚本绝对有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 php 和 htaccess 中上传图像的安全方法 的相关文章

  • PHP 中的encodeURI() ?

    PHP 中是否有一些不编码的encodeURI 函数 我现在用这个 function encodeURI url http php net manual en function rawurlencode php https develope
  • 通过身份验证保护 CodeIgniter 2 应用程序的正确方法是什么?

    I have Ion Auth http benedmunds com ion auth 正确安装并在我的服务器上运行 我也有默认的代码点火器2 新闻 教程在同一个 CI 安装中工作 我只是在玩 并对使用身份验证系统 封闭 或保护整个应用程
  • 使用 MYSQL 将 h:mm pm/am 时间格式插入数据库

    我正在尝试将以 h mm am pm 格式写入的时间插入到存储为标准 DATETIME 格式 hh mm ss 的数据库中 但我不知道如何将发布的时间转换为标准格式所以数据库会接受它 这是我到目前为止一直在尝试的 title POST in
  • if/else 简写来定义变量

    我很难理解 if else 的 php 简写是如何描述的here https stackoverflow com questions 20233207 php if shorthand and echo in one line possib
  • 我可以让 swagger-php 在查询字符串上使用数组吗?

    我使用 Swagger php 当我定义查询字符串上的参数时 它可以是一个数组 但据我所知 它不支持这种查询字符串 https api domain tld v1 objects q 1 q 5 q 12 我相信这会被设定in the co
  • 正则表达式上的换行符

    我试图替换两个标签之间的所有内容 但我无法构建正确的表达式 这就是我所做的
  • Symfony2:为什么请求传递到受 Symfony2 中 AppCache 影响的 Kernel.Terminate EventListener

    在我的 Symfony2 2 应用程序中 我使用 onKernelTerminate EventListener 以便我可以在渲染响应后进行一些 繁重 处理 以便用户收到更快的响应时间 在我的控制器中 我在请求上设置了一个属性 以便当事件侦
  • 使用 ImageMagick 和 PHP 将 PNG 转换为 JPG 并将透明背景设置为白色

    将图像从 PNG 转换为 JPEG 时 如何使用 ImageMagick 带有 php 扩展 将透明背景设置为白色 在撰写本文时 您尚未指定正在使用哪个扩展 但如果您使用命令行 则命令将是 convert image png backgro
  • php中的条件格式化html表与时间戳比较

    echo table style width 100 tr echo td Order td echo td Destination td echo td Location td echo td Status td echo td Time
  • 如何对 SQL 进行多次查询

    我正在尝试创建一个表 并在 PHP 脚本的帮助下在数据库中插入一些值 虽然只插入 1 行 但效果很好 当我尝试输入更多行数时 出现错误 我需要为每个查询编写完整的插入语句 因为我正在使用在线 Excel 到 SQL 查询转换器
  • 如何隐藏 URL 中的锚标记

    如何隐藏地址栏中以下链接 href 的哈希值 a href index php dev name 所以它会将我重定向到index php dev name 但我希望地址栏只显示index php 您可以使用 Javascript oncli
  • 如何关闭未关闭的 HTML 标签?

    每当我们从数据库或类似来源获取一些经过编辑的用户输入内容时 我们可能会检索仅包含开始标记但不包含结束标记的部分 这可能会妨碍网站当前的布局 有客户端或服务器端的方法来解决这个问题吗 找到了一个很好的答案 使用 PHP 5 并使用 DOMDo
  • CodeIgniter 控制器 - JSON - AJAX

    我正在尝试通过 AJAX 使用 CodeIgniter 发送表单构建 并尝试使用 JSON 获取响应 但是 我只在打开开发人员选项卡时看到响应 我什至不确定这是否实际上是响应 因为它显示了两个 json 数据 它所显示的只是加载旋转器 然后
  • 如何防止在 PHP 中使用超出“使用”范围的特征方法

    我想知道是否有任何方法可以防止在 PHP 的任何类上下文之外使用特征方法 让我用一个简短的例子来解释我想要什么 这是我当前的代码 File MyFunctions php trait MyFunctions function hello w
  • 通过 URL 指定控制器类与为每个控制器编写一个脚本相比,有何优缺点?

    今年夏天我安装了两个不同的 PHP 系统 每个都使用两种不同的方法 方法 1 每个任务一个 PHP 文件 该方法需要一个PHP为每个主要任务创建文件 例如 我的上传脚本可以通过http www domain com upload php O
  • 在 WooCommerce 中添加到购物车之前清空购物车

    我正在使用 WP 作业管理器和 Woo Subscriptions Now 最初 我选择了一个套餐 Woo Subscription 然后我添加了所有细节 但没有提交 回到网站 所以要再次购买 我需要选择一个套餐 于是我选择了套餐并填写了详
  • 如何通过php获取网页的Open Graph协议?

    PHP 有一个简单的命令来获取网页的元标记 get meta tags 但这仅适用于具有名称属性的元标记 然而 开放图谱协议如今变得越来越流行 从网页获取 opg 值的最简单方法是什么 例如 我看到的基本方法是通过 cURL 获取页面并使用
  • 如何通过ssh检查ubuntu服务器上是否存在php和apache

    如何通过ssh检查Ubuntu服务器上apache是 否安装了php和mysql 另外如果安装的话在哪个目录 如果安装了其他软件包 例如 lighttpd 那么它在哪里 确定程序是否已安装的另一种方法是使用which命令 它将显示您正在搜索
  • 如何删除文件

    我们有一个脚本 scripts ourscript php和一个文件 media movie1 flv 当我们运行时 我们如何删除这个文件ourscript php Using unlink http php net manual en f
  • ZF3/2 - 如何捕获 EVENT_DISPATCH 侦听器中引发的异常?

    有什么方法可以在 EVENT DISPATCH 监听器中抛出异常吗 class Module public function onBootstrap EventInterface event application event gt get

随机推荐

  • 强制转换 (int?)null 与 new int?() - 哪个更好?

    I use Nullable
  • 没有默认构造函数的值初始化

    我想知道在什么情况下一个类可能没有默认构造函数但仍然会被值初始化 无默认构造函数 的典型情况是存在参数化构造函数但不存在默认构造函数违约 default 引用 2020 年标准第 9 4 1 章 初始化器 常规 最新草案包含等效措辞 对 T
  • Android:正弦波生成

    我正在尝试使用 AudioTrack 生成正弦波 方波和锯齿波 然而 它创建的音频听起来不像纯正弦波 而是像叠加了某种其他波 在使用第一个示例中的方法的同时 如何获得像第二个代码示例中那样的纯正弦波 由于上面的例子只涉及第二个例子中使用的一
  • Git hooks - 如何仅处理属于存储库内特定文件夹的文件?

    我对 git 有点陌生 对 bash 不太擅长 我有一个存储库 如果重要的话 在 Bitbucket 中 它只包含两个文件夹 我已经有一个钩子 用 bash 编写 可以触发 Jenkins 作业 现在我想更改它 因此它将仅针对提交到其中一个
  • 从另一个包加载 spritekit 场景?

    我正在使用 swift 4 2 制作 SpriteKit 框架 并希望包含一些用于场景和动作的 sks 文件 我尝试使用以下代码从包中加载场景 class func newGameScene gt GameScene guard let g
  • 设置文本时停止调整 UITextField 大小

    我有一个视图设置 其中布局了 4 个 UITextFields 并设置了约束 以便它在所有设备上看起来都很棒并且按预期工作 我有一个问题 如果我使用 TextField text some long text 设置文本或 TextField
  • 如何从 sqlite (3.6.21) 表中删除约束?

    我有下表 CREATE TABLE child id INTEGER PRIMARY KEY parent id INTEGER CONSTRAINT parent id REFERENCES parent id description T
  • 跨隐藏跨度搜索文本 (Ctrl+F)

    Is it possible to search for text using your browser s Ctrl F function across three span tags if the middle tag is set t
  • 突出显示特定日期(来自 bean 的值)

    使用素面
  • C++11 中的纯函数

    C 11 中的一个可以以某种方式gcc将函数 不是类方法 标记为const告诉它是pure并且不使用全局内存而仅使用其参数 我试过了gcc s attribute const 它是恰恰我想要的是 但当函数中触及全局内存时 它不会产生任何编译
  • PHP $_POST 不带重音符号

    这个问题已经解决了 看我的回答看看解决方案 我试图通过使用 POST 提交到 PHP 页面的 html 表单向我的数据库添加带有重音字母的文本 问题是重音字母被转换为不可读的字符 我有这个表格
  • 在目录树中查找具有给定扩展名的文件

    我有一个文件夹 其中有一些文件和子文件夹 例如 我需要返回具有给定扩展名的文件名或相对地址 如果文件位于子文件夹中 html 例如 这是给定文件夹的结构 文本 某事 ncx 文本 123 html 内容 opf toc ncx Flow 0
  • Ctrl+。 (点) 使“e”出现,而不是在 Gnome 上的 VSCode 中显示建议

    我在 Gnome 上使用 VSCode 在 Arch 上的 XOrg 上 最近以来 捷径Ctrl 停止工作 尽管仍然列在键盘快捷键中并且所有扩展都被禁用 相反 带有下划线的e出现 当按两次 Enter 或按一次 ESC 时 该字符消失 当写
  • MySQL Join on LIKE 语句

    我需要计算数据库中每个组中有多少用户 不幸的是 数据库设计不是很好 用户 uid 是针对组表中的组存储在 LONGTEXT 字段列名称 owncloudusers 中 owncloudusers 数据示例 i 0 s 36 25C967BD
  • 使用不同的 dockerfiles 从源目录构建 docker 镜像

    我的目标是从相同的源代码构建几个不同的 docker 镜像 我有我的 src 文件夹 node js 项目 在 src 内我有第一个 dockerfile 和第二个 dockerfile 为了构建项目 我使用这个标准命令行 sudo doc
  • 如何在 Rails 7 引擎中使用 Tailwind CSS gem?

    如何在轨道发动机中使用顺风 根据文档 向 Rails 生成器提供 css 参数应该可以工作 使用 Rails 7 0 2 2 引擎生成 rails plugin new tailtest mountable full d postgresq
  • Android PhoneGap 通知状态栏不显示任何内容

    我正在尝试使用名为的 Phonegap 插件在 Android 模拟器设备上显示通知消息StatusBarNotification LINK https github com phonegap phonegap plugins tree m
  • ASP.NET MVC 软件设计模式:DI、存储库、服务层

    EDIT 我是否应该将服务层和存储库层放入一个项目中 以便 Web 项目能够引用 DbContext 对象 现在我的网络 控制器 无法引用 dbcontext 对象 什么是正确的方法 service and repository are t
  • AngularJS 访问嵌套 ngRepeat 中 ngRepeat 父级的 $first

    我试图从嵌套的 ngRepeat 中访问 ngRepeat 父级的 first 有没有办法在嵌套的 ngRepeat 中使用别名或访问 first 我已经尝试过 parent first 但它似乎不起作用 通过插值输出到屏幕表明它与嵌套子级
  • 在 php 和 htaccess 中上传图像的安全方法

    我在互联网上找到了以下代码 用于在 php 中安全上传图像 我想知道它涵盖了图像上传中所有可能的攻击方式 define MAX SIZE EXCEDED 101 define UPLOAD FAILED 102 define NO UPLO