Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
安全图像上传PHP_Php_Mysql_File Upload - Fatal编程技术网

安全图像上传PHP

安全图像上传PHP,php,mysql,file-upload,Php,Mysql,File Upload,在我的网站上,我允许用户使用以下方式上传图像 $max_filesize = 1572864; // 1.5MB $upload_path = 'uploads'; $upload_path = $upload_path.'/'; $filename = $_FILES['profile_image']['name']; if(filesize($_FILES['profile_image']['tmp_name']) > $max_filesize) die('Th

在我的网站上,我允许用户使用以下方式上传图像

$max_filesize = 1572864; // 1.5MB
$upload_path = 'uploads'; 
$upload_path = $upload_path.'/';

$filename = $_FILES['profile_image']['name']; 


if(filesize($_FILES['profile_image']['tmp_name']) > $max_filesize)
      die('The file you attempted to upload is too large.'); 
if(!is_writable($upload_path))
      die('permission errorrr!'); 

if(move_uploaded_file($_FILES['profile_image']['tmp_name'],$upload_path . $filename)){
    // TA DA!
}

我刚刚就如何确保这一点,以及如何使其更加安全发表了一些意见,我要求当我设法将.png文件更改为.jpg并上传时,理论上可以重命名并上传.exe,如果是这样,如何应对?

我认为.exe文件不能重命名。否则它将成为损坏的文件,因此不建议重命名.exe文件,在php文件中,使用post方法上载数据,这样数据就不可见,因此它是安全的。

您可以使用此示例。如果不是图像,则返回false:

if (!getimagesize($_FILES['profile_image']['tmp_name'])){
    die('Not an image');
}

您在这里关心的不是exe可以上传(因为有办法绕过任何安全性,甚至MIME),而是这个exe以后是否可以执行(只是上传一个exe文件不会执行它,它只会放在那里)


但是如果你想得到它,我建议你去做。强制文件扩展也是一种方法(因此MIME图像/png将被更改,因此扩展名将为.png,而不是用户放在那里的任何内容)。

MIME类型不可信,因此,正如@yoeriboven所说,您可以使用:

if (!getimagesize($_FILES['profile_image']['tmp_name'])){
    die('Not an image');
}
但您也不能允许执行上载到uploads文件夹的任何文件。您可以使用
.htaccess
(假设您使用的是Apache)执行以下操作:

AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi
Options -ExecCGI
为了帮助用户,您还可以使用HTML5的
accept
属性:

<input type="file" name="file" accept="image/gif, image/jpeg" />


(显然,上述内容可以在客户端更改,因此不必依赖)

您可以先检查文件扩展名,但有些人可能会试图伪造文件扩展名,以便:

ForceType application/octet-stream
<FilesMatch "(?i)\.jpe?g$">
    ForceType image/jpeg
</FilesMatch>
<FilesMatch "(?i)\.gif$">
    ForceType image/gif
</FilesMatch>
<FilesMatch "(?i)\.png$">
    ForceType image/png
</FilesMatch>
ForceType应用程序/八位字节流
ForceType图像/jpeg
ForceType图像/gif
ForceType图像/png

此代码放在上载目录的.htaccess文件中,只允许图像与其默认处理程序关联。其他所有内容都将作为普通字节流使用,不会运行任何处理程序。(查看本文)

这是我不久前用于图像上传的函数。 它将检查jpeg文件的幻数并返回true或false

function checkMagicNumberJPEG ($filename) {
    // Open file and read first 2 btytes
    $file = fopen($filename, 'r');
    $contents = fread($file, 2);

    $ascii = '';

    // Convert to hex
    for ($i = 0; $i < strlen($contents); $i++) { 
        $ascii .= dechex(ord($contents[$i])); 
    }

    // Close file
    fclose($file);

    // Check magic number
    if($ascii == 'ffd8') {
        return true;
    } else {
        return false;
    }
}
函数checkMagicNumberJPEG($filename){
//打开文件并读取前2个字节
$file=fopen($filename,'r');
$contents=fread($file,2);
$ascii='';
//转换为十六进制
对于($i=0;$i
检查文件的mime类型()还检查这是您的服务器配置为执行
.jpg
文件吗?