我正在制作图片上传功能,我可以在我的代码中重复使用,必须100%安全。请告诉我你是否可以在我的初始代码中找到并发现安全性;
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!';
}
}
}
谢谢!
UPDATE;这是我得到你的帮助和一些研究,请告诉我你的想法。我不太关心速度,对我而言,这一切都是关于100%安全,或接近。
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!';
}
}
}
}
}
}
再次感谢!
答案 0 :(得分:2)
只要你不使用php的FileInfo
(http://www.php.net/manual/en/ref.fileinfo.php)扩展来检查mime类型,你的功能根本就不安全(想想以后你会想要上传pdf的,擅长等)
此外,md5超过md5只会增加碰撞几率。
L.E:以下简单的事情应该这样做:
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}");
}
}
答案 1 :(得分:0)
通过mime类型停止过滤它不安全!
客户端可以发送具有不同文件扩展名的不同mime类型。因此,您需要检查文件扩展名。
编辑:
我认为我被误解了,我写的答案告诉我,检查mime类型确定文件类型不是一个好方法,确定文件类型的最好方法是检查文件扩展名。所以,我并不是说检查文件扩展名就足够了。只检查文件扩展名或mime类型是不安全的方式。怎么办? 1 - 检查哑剧类型
2 - 检查文件扩展名
3-解码文件名
4-检查文件内容的一致性(如果可能)
5-重新生成文件内容(如果可能)
我知道攻击者可以通过使用“null byte hack”和“mime type bypass”来绕过第一种和第二种方式
因此,3,4和5对安全性非常重要。