在PHP中安全上传图片 [英] Secure image upload in php

查看:126
本文介绍了在PHP中安全上传图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个图像上传功能,我可以在我的代码中重复使用,这必须是100%安全的。请告诉我你是否可以在我的初始代码中发现和安全整体;

I am making an image upload function which I can re-use in my code, which has to be 100% secure. Please tell me if you can spot and security wholes in my initial code;

function Upload($file)
{
    list($width,$height,$type,$attr) = getimagesize($file);
    $mime = image_type_to_mime_type($type);

    if(($mime != "image/jpeg") && ($mime != "image/pjpeg") && ($mime != "image/png")) 
    {
        return 'Error3: Upload file type un-recognized. Only .JPG or .PNG images allowed';
    }else{
        $Newname = md5('sillysalt'.time());
        if (move_uploaded_file($file, 'images/'.$Newname.$type)) 
        {
            return 'Uploaded!';
        }else{
            return 'Server Error!';
        } 
    }
}

谢谢!

更新;这是我得到你的帮助和一些研究,请告诉我你的想法。我不太关心速度,对我而言,这一切都是关于100%安全,或接近。

UPDATE; This is how far I've gotten with your help and some research, please tell me what you think. I don't mind much about the speed, for me it's all about being 100% secure, or as close to.

function Upload($file)
{
    list($width,$height,$type,$attr) = getimagesize($file);
    $mime = image_type_to_mime_type($type);
    $folder = 'images/';

    // mime checks add a layer of security that keeps out less sophisticated attackers 
    if(($mime != "image/jpeg") && ($mime != "image/pjpeg") && ($mime != "image/png")) 
    {
        return 'Error3: Upload file type un-recognized. Only .JPG or .PNG images allowed';
    }else{
        // If the file has no width its not a valid image
        if(!$width)
        {
            $Newname = md5('sillysalt'.time());
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mime2 = finfo_file($finfo, $folder.$Newname);

            // Should I remove this second mime check? since the info comes form the same spoofable source in the image
            if(($mime != "image/jpeg") && ($mime != "image/pjpeg") && ($mime != "image/png")) 
            {
                $fileType = exif_imagetype($file);
                $allowed = array(IMAGETYPE_JPEG, IMAGETYPE_PNG);
                if(!in_array($fileType, $allowed))
                {
                    // don't overwrite an existing file
                    $i = 0;
                    $parts = pathinfo($file);
                    while(file_exists($folder . $name))
                    {
                        $i++;
                        $name = $Newname."-".$i.".".$parts["extension"];
                    }

                    if(move_uploaded_file($file, $folder.$name)) 
                    {
                        // set good permissions for the file
                        chmod($name, 0644);
                        return 'Uploaded!';
                    }else{
                        return 'Server Error!';
                    } 
                }
            }
        }
    }
}

再次感谢!

推荐答案

只要您不使用 FileInfo http://www.php。 net / manual / en / ref.fileinfo.php )来自php的扩展来检查mime类型,你的功能根本不安全(想想以后你会想要上传pdf,excels等)。 >
另外,md5超过md5只会增加碰撞几率。

As long as you don't use the FileInfo (http://www.php.net/manual/en/ref.fileinfo.php) extensions from php to check the mime type, your function is not secure at all (think later you'll want to upload pdf's, excels, etc).
Also, md5 over md5 does nothing than increasing the collision chances.

LE:如下所示的简单操作:

function getExtensionToMimeTypeMapping() {
    return array(
        'ai'=>'application/postscript',
        'aif'=>'audio/x-aiff',
        'aifc'=>'audio/x-aiff',
        'aiff'=>'audio/x-aiff',
        'anx'=>'application/annodex',
        'asc'=>'text/plain',
        'au'=>'audio/basic',
        'avi'=>'video/x-msvideo',
        'axa'=>'audio/annodex',
        'axv'=>'video/annodex',
        'bcpio'=>'application/x-bcpio',
        'bin'=>'application/octet-stream',
        'bmp'=>'image/bmp',
        'c'=>'text/plain',
        'cc'=>'text/plain',
        'ccad'=>'application/clariscad',
        'cdf'=>'application/x-netcdf',
        'class'=>'application/octet-stream',
        'cpio'=>'application/x-cpio',
        'cpt'=>'application/mac-compactpro',
        'csh'=>'application/x-csh',
        'css'=>'text/css',
        'csv'=>'text/csv',
        'dcr'=>'application/x-director',
        'dir'=>'application/x-director',
        'dms'=>'application/octet-stream',
        'doc'=>'application/msword',
        'drw'=>'application/drafting',
        'dvi'=>'application/x-dvi',
        'dwg'=>'application/acad',
        'dxf'=>'application/dxf',
        'dxr'=>'application/x-director',
        'eps'=>'application/postscript',
        'etx'=>'text/x-setext',
        'exe'=>'application/octet-stream',
        'ez'=>'application/andrew-inset',
        'f'=>'text/plain',
        'f90'=>'text/plain',
        'flac'=>'audio/flac',
        'fli'=>'video/x-fli',
        'flv'=>'video/x-flv',
        'gif'=>'image/gif',
        'gtar'=>'application/x-gtar',
        'gz'=>'application/x-gzip',
        'h'=>'text/plain',
        'hdf'=>'application/x-hdf',
        'hh'=>'text/plain',
        'hqx'=>'application/mac-binhex40',
        'htm'=>'text/html',
        'html'=>'text/html',
        'ice'=>'x-conference/x-cooltalk',
        'ief'=>'image/ief',
        'iges'=>'model/iges',
        'igs'=>'model/iges',
        'ips'=>'application/x-ipscript',
        'ipx'=>'application/x-ipix',
        'jpe'=>'image/jpeg',
        'jpeg'=>'image/jpeg',
        'jpg'=>'image/jpeg',
        'js'=>'application/x-javascript',
        'kar'=>'audio/midi',
        'latex'=>'application/x-latex',
        'lha'=>'application/octet-stream',
        'lsp'=>'application/x-lisp',
        'lzh'=>'application/octet-stream',
        'm'=>'text/plain',
        'man'=>'application/x-troff-man',
        'me'=>'application/x-troff-me',
        'mesh'=>'model/mesh',
        'mid'=>'audio/midi',
        'midi'=>'audio/midi',
        'mif'=>'application/vnd.mif',
        'mime'=>'www/mime',
        'mov'=>'video/quicktime',
        'movie'=>'video/x-sgi-movie',
        'mp2'=>'audio/mpeg',
        'mp3'=>'audio/mpeg',
        'mpe'=>'video/mpeg',
        'mpeg'=>'video/mpeg',
        'mpg'=>'video/mpeg',
        'mpga'=>'audio/mpeg',
        'ms'=>'application/x-troff-ms',
        'msh'=>'model/mesh',
        'nc'=>'application/x-netcdf',
        'oga'=>'audio/ogg',
        'ogg'=>'audio/ogg',
        'ogv'=>'video/ogg',
        'ogx'=>'application/ogg',
        'oda'=>'application/oda',
        'pbm'=>'image/x-portable-bitmap',
        'pdb'=>'chemical/x-pdb',
        'pdf'=>'application/pdf',
        'pgm'=>'image/x-portable-graymap',
        'pgn'=>'application/x-chess-pgn',
        'png'=>'image/png',
        'pnm'=>'image/x-portable-anymap',
        'pot'=>'application/mspowerpoint',
        'ppm'=>'image/x-portable-pixmap',
        'pps'=>'application/mspowerpoint',
        'ppt'=>'application/mspowerpoint',
        'ppz'=>'application/mspowerpoint',
        'pre'=>'application/x-freelance',
        'prt'=>'application/pro_eng',
        'ps'=>'application/postscript',
        'qt'=>'video/quicktime',
        'ra'=>'audio/x-realaudio',
        'ram'=>'audio/x-pn-realaudio',
        'ras'=>'image/cmu-raster',
        'rgb'=>'image/x-rgb',
        'rm'=>'audio/x-pn-realaudio',
        'roff'=>'application/x-troff',
        'rpm'=>'audio/x-pn-realaudio-plugin',
        'rtf'=>'text/rtf',
        'rtx'=>'text/richtext',
        'scm'=>'application/x-lotusscreencam',
        'set'=>'application/set',
        'sgm'=>'text/sgml',
        'sgml'=>'text/sgml',
        'sh'=>'application/x-sh',
        'shar'=>'application/x-shar',
        'silo'=>'model/mesh',
        'sit'=>'application/x-stuffit',
        'skd'=>'application/x-koan',
        'skm'=>'application/x-koan',
        'skp'=>'application/x-koan',
        'skt'=>'application/x-koan',
        'smi'=>'application/smil',
        'smil'=>'application/smil',
        'snd'=>'audio/basic',
        'sol'=>'application/solids',
        'spl'=>'application/x-futuresplash',
        'spx'=>'audio/ogg',
        'src'=>'application/x-wais-source',
        'step'=>'application/STEP',
        'stl'=>'application/SLA',
        'stp'=>'application/STEP',
        'sv4cpio'=>'application/x-sv4cpio',
        'sv4crc'=>'application/x-sv4crc',
        'swf'=>'application/x-shockwave-flash',
        't'=>'application/x-troff',
        'tar'=>'application/x-tar',
        'tcl'=>'application/x-tcl',
        'tex'=>'application/x-tex',
        'texi'=>'application/x-texinfo',
        'texinfo'=>'application/x-texinfo',
        'tif'=>'image/tiff',
        'tiff'=>'image/tiff',
        'tr'=>'application/x-troff',
        'tsi'=>'audio/TSP-audio',
        'tsp'=>'application/dsptype',
        'tsv'=>'text/tab-separated-values',
        'txt'=>'text/plain',
        'unv'=>'application/i-deas',
        'ustar'=>'application/x-ustar',
        'vcd'=>'application/x-cdlink',
        'vda'=>'application/vda',
        'viv'=>'video/vnd.vivo',
        'vivo'=>'video/vnd.vivo',
        'vrml'=>'model/vrml',
        'wav'=>'audio/x-wav',
        'wrl'=>'model/vrml',
        'xbm'=>'image/x-xbitmap',
        'xlc'=>'application/vnd.ms-excel',
        'xll'=>'application/vnd.ms-excel',
        'xlm'=>'application/vnd.ms-excel',
        'xls'=>'application/vnd.ms-excel',
        'xlw'=>'application/vnd.ms-excel',
        'xml'=>'application/xml',
        'xpm'=>'image/x-xpixmap',
        'xspf'=>'application/xspf+xml',
        'xwd'=>'image/x-xwindowdump',
        'xyz'=>'chemical/x-pdb',
        'zip'=>'application/zip',
    );
}

function getMimeType($filePath) {

    if (!is_file($filePath)) {
        return false;
    }

    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime = finfo_file($finfo, $filePath);
    finfo_close($finfo);

    return $mime;
}

function upload($filePath, $destinationDir = 'images', array $allowedMimes = array()) {

    if (!is_file($filePath) || !is_dir($destinationDir)) {
        return false;
    }

    if (!($mime = getMimeType($filePath))) {
        return false;
    }

    if (!in_array($mime, $allowedMimes)) {
        return false;
    }

    $ext = null;
    $extMapping = getExtensionToMimeTypeMapping();
    foreach ($extMapping as $extension => $mimeType) {
        if ($mimeType == $mime) {
            $ext = $extension;
            break;
        }
    }

    if (empty($ext)) {
        $ext = pathinfo($filePath, PATHINFO_EXTENSION);
    }

    if (empty($ext)) {
        return false;
    }

    $fileName = md5(uniqid(rand(0, time()), true)) . '.' . $ext;
    $newFilePath = $destinationDir.'/'.$fileName;

    if(!rename($filePath, $newFilePath)) {
        return false;
    }

    return $fileName;
}

// use it 
if (isset($_FILES['something']['tmp_name'])) {
    $file = $_FILES['something']['tmp_name'];
    $storagePath = 'images'; // this is relative to this script, better use absolute path.
    $allowedMimes = array('image/png', 'image/jpg', 'image/gif', 'image/pjpeg');

    $fileName = upload($file, $storagePath, $allowedMimes);
    if (!$fileName) {
        exit ('Your file type is not allowed.');
    } else {
         // check if file is image, optional, in case you allow multiple types of files.
         // $imageInfo = @getimagesize($storagePath.'/'.$fileName);
        exit ("Your uploaded file is {$fileName} and can be found at {$storagePath}/{$fileName}");
    }
}

这篇关于在PHP中安全上传图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆