简体   繁体   English

如何查看上传的文件扩展名?

[英]How can I check uploaded files extension?

How can I check the uploaded files extension in the following code(I already wrote a file type checking)? 如何在以下代码中检查上传的文件扩展名(我已经编写了文件类型检查)? I want to prevent uploading image files with wrong extension, like *.jpg.exe. 我想防止上传带有错误扩展名的图像文件,例如* .jpg.exe。

My code: 我的代码:

<?php

class Uploader {

    private $fileName;
    private $fileData;
    private $destination;

    public function __construct($key){
        $this->fileName = $_FILES[$key]['name'];
        $this->fileData = $_FILES[$key]['tmp_name'];
    }

    public function saveIn($folder){
        $this->destination = $folder;
    }

    public function save(){

        $folderWriteAble = is_writable($this->destination);
        if($folderWriteAble && (exif_imagetype($this->fileData) == IMAGETYPE_JPEG)){
            $name = "$this->destination/$this->fileName";
            $success = move_uploaded_file($this->fileData, $name);
        } else {
            trigger_error("cannot write to $this->destination");
            $success = false;
        }

        return $success;

    }

} 

If you run on your server(s) linux I would check the file content type with the command file that returns the real mime type of the file. 如果您在服务器linux上运行,我将使用命令file检查文件内容类型,该命令file返回file的真实mime类型。 Than you can be sure what that content is (in most cases). 比您可以确定该内容是什么(在大多数情况下)。

That programm uses that magic bytes. 该程序使用该魔术字节。 The orginal idea is to check the first view bytes and check if a file contains a known pattern, eg "MZ" for windows executables or "‰PNG" for png files. 原始的想法是检查第一个视图字节,并检查文件是否包含已知模式,例如,对于Windows可执行文件为“ MZ”,对于png文件为“‰PNG”。 However that file programm does also some more things than only the basic set of the first view bytes. 但是,该file程序除仅具有基本的第一个视图字节集外,还执行其他一些操作。


Depending on the comments, you are concerned about wrong, eg double file extensions. 根据注释,您会担心错误,例如,双文件扩展名。 I would say don't think about it and just rename that file, in best case with some random name. 我会说不要考虑它,只是重命名该文件,最好是使用一些随机名称。 That could be also helpful if you worry about that somebody just counts up some file numbers to see unpublished images. 如果您担心有人只是计算一些文件编号以查看未发布的图像,这也可能会有所帮助。

我认为您已经在(exif_imagetype($this->fileData) == IMAGETYPE_JPEG)上执行了此操作,但是此处对此进行了很好的讨论: https : (exif_imagetype($this->fileData) == IMAGETYPE_JPEG) 检查使用PHP上传文件的文件类型的方法

Use getimagesize which checks the first three bits in the file. 使用getimagesize来检查文件中的前三位。 Note that $_FILES isn't secure as it reads the extension (which people can change of course), vs getimagesize which reads permission bits. 请注意,$ _ FILES是不安全的,因为它读取扩展名(人们当然可以更改),而getimagesize读取允许位。

Usage: 用法:

$image = getimagesize($_FILES['image']['tmp_name']);

$filetype = $image['mime'];

Hope this helps 希望这可以帮助

I know this won't necessarily answer your specific question, but a good way to prevent "PHP images" to be "executed" is to have images served from a place that doesn't execute PHP scripts and only serves static images (ie: nginx, if properly configured). 我知道这不一定能回答您的特定问题,但是防止“ PHP图像”被“执行”的一个好方法是从不执行PHP脚本而仅提供静态图像的位置提供图像(即: nginx(如果配置正确)。 It could even be an external CDN or just a simple directory that doesn't run php. 它甚至可以是外部CDN,也可以只是一个不运行php的简单目录。

That being said, you can also try: 话虽如此,您也可以尝试:

1- Make sure file type is (jpg, gif or png)
2- Make sure dimensions are numbers
3- Make sure file size does not exceed allowed size
4- Make sure file is not executable by anyone else (proper chmod settings are important in shared environment).
5- Rename and convert all uploads through imagemagick to jpg (or your desired format)

Use GD library to test if your upload is a jpg and in addition, check if it also returns false for partially uploaded images: 使用GD库测试您上传的文件是否为jpg,此外,请检查部分上传的图片是否还返回false:

$image = @imagecreatefromjpeg($this->fileData);
if(!$image) { imagedestroy($image); return false; } // file is not a jpg
else { imagedestroy($image); return true; } // file is a jpg

If you can use exec(), you may also invoke the unix file utility for checking the bynary signatures. 如果可以使用exec(),则还可以调用unix文件实用程序来检查通用签名。

// verify that the file is a jpg
$mime = "image/jpeg; charset=binary";
exec("file -bi " . $this->fileData, $out);
if ($out[0] != $mime) {
    // file is not a jpg
    ...

If you have ClamAV installed you can also check for virus with the exec command: 如果安装了ClamAV,则还可以使用exec命令检查病毒:

exec("clamscan --stdout " . $this->fileData, $out, $return);
if ($return) {
    // file is infected
    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM