2013-06-05 140 views
0

在我的網站,我允許用戶使用以下上傳圖片...安全圖片上傳PHP

$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,如果可以的話,如何解決這個問題?

+0

檢查文件的MIME類型(http://php.net/manual/es/function.mime-content-type.php)也檢查這個http://stackoverflow.com/questions/4166762/php-image-upload-security-check-list?rq = 1 – Xavi

+0

您的服務器是否配置爲執行'.jpg'文件? –

回答

2

MIME類型不能被信任,因此,作爲@yoeriboven說,你可以使用:

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

但你也不能讓上傳到您的上傳文件夾中的所有文件的執行。你可以用.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" /> 

(明明上面可以改變客戶端,所以它不被倚重)

+0

感謝@Prisoner – Liam

1

我認爲.exe文件無法重命名。否則它會變成損壞的文件,所以不建議重命名.exe文件,並在PHP文件上傳數據使用post方法,所以數據不可見,因此它是安全的。

1

你可以用這個例子。這將返回false,如果它不是一個形象:

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

這裏您的關注是不是exe文件,可以上傳(因爲有辦法去解決任何安全性,即使MIME),但這個exe文件以後執行(只上傳一個exe文件不會執行它,它只會躺在那裏)?

但是,如果你想保護它,我建議reading up on MIME types,並通過它。強制擴展文件也是一種方式(所以一個MIME圖像/ PNG將被改變,所以擴展名將是.png,而不是用戶放置的任何東西)。

2

您可以先檢查文件的擴展名,但有些人可能試圖篡改它,以便:

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> 

此代碼放置在上傳目錄中的.htaccess文件中,僅允許圖像與其默認處理程序相關聯。其他所有內容將作爲普通字節流提供,並且不會運行任何處理程序。 (檢查這篇文章[1]

0

這是我前段時間用於我的圖像上傳器的函數。 它會檢查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; 
    } 
}