2010-01-08 31 views
3

我正在構建一個php文件上傳器,並且我遇到了一些安全問題。例如,我不想允許「.php」文件上傳。據我所知,檢查文件類型的唯一方法是使用$_FILES['file']['type'],它的值取決於瀏覽器。上傳時檢查文件類型和瀏覽器依賴性問題

我檢查有多種瀏覽器和發現,選擇正規PHP文件時,不同的瀏覽器返回這些值:

firefox: application/x-download 
chrome: text/plain 
safari: text/plain 
IE: text/plain 
opera: application/octet-stream 

我也試過同樣的實驗與普通.txt文件和所有瀏覽回報作爲mime類型的text/plain

所以,這裏的問題,如果我想允許.txt文件上傳我該怎麼做,以防止.php文件上傳?

+0

出於安全原因,您還必須在允許文件上傳到的目錄中禁用php。 (如果你的主機默認解釋.php3文件,並且你沒有注意到,等等)。在.htaccess文件中使用「php_flag engine off」 – 2010-01-11 07:53:23

回答

2

使用下面的函數:

function Mime($path) 
{ 
    $result = false; 

    if (is_file($path) === true) 
    { 
     if (function_exists('finfo_open') === true) 
     { 
      $finfo = finfo_open(FILEINFO_MIME_TYPE); 

      if (is_resource($finfo) === true) 
      { 
       $result = finfo_file($finfo, $path); 
      } 

      finfo_close($finfo); 
     } 

     else if (function_exists('mime_content_type') === true) 
     { 
      $result = preg_replace('~^(.+);.*$~', '$1', mime_content_type($path)); 
     } 

     else if (function_exists('exif_imagetype') === true) 
     { 
      $result = image_type_to_mime_type(exif_imagetype($path)); 
     } 
    } 

    return $result; 
} 

這將返回適當的MIME類型的任何文件。

+0

整潔的代碼。謝謝。 – Haluk 2010-09-09 22:43:40

+0

使用這段代碼我從各種文件類型中得到很多的錯誤......尤其是那些來自OpenOffice的錯誤。 – Jon 2010-12-14 16:37:41

3

不要依賴客戶端發送的信息。即使是客戶端發送的媒體類型也可以僞造。

如果您不希望允許PHP文件,只是不允許文件擴展.php文件,或將其更改爲.txt

if (strtolower(strrchr($_FILES['file']['name'], '.')) == '.php') { 
    // has file extension .php 
} 
0

嘗試以下。這是從不勞而獲的FAR,但它是一個快速檢查。它會阻止任何標記.PHP(因爲它是在客戶機上),所以,如果他們有這樣的事情「do_evil.php.txt」,它會允許,但(閱讀代碼註釋)

$file_ext = substr($_FILES['userfile']['name'], -3); 
if($file_ext == 'php') { 
    //REJECT FILE 
} 
else { 
    // allow upload and once the file has been upload to the temp directory 
    // have a peice of code move the file to the final location and rename 
    // the file and specify a new file extension, using $file_ext as the extension 
    // so even if the file was 'do_evil.php.txt' when it comes to rest at the 
    // final location it will be 'do_evil.txt' and thus treated by the server as a 
    // text file and not PHP 
} 

我已經使用以上在過去與下降的結果。這絕不是防彈的,但至少應該有所幫助。我想我可能有一些代碼躺在附近,它所有的,如果你需要它生病去尋找它,但沒有承諾我能找到它

+0

這也會阻止「php」或「foo.notphp」。 – Gumbo 2010-01-08 13:36:40

+0

大多數人不會剝奪他們的文件擴展名(如果他們有一個),誰將給文件一個.not ???延期? 但你的權利。就像我說的遠不是傻瓜證明,但它作爲一個止損缺口 – DBunting 2010-01-08 13:49:22

+0

我更喜歡下面的代碼來確定擴展名: $ extention = strtolower(end(explode('。',$ _FILES ['userfile'] ['name' ]))); – 2010-01-09 06:52:49