2012-04-24 60 views
2

新人在這裏問一個問題,應該遇到什麼簡單的解決方案。驗證文件上傳服務器端 - 只允許圖像與php

我試了一堆代碼。看起來我可以獲取getimagesize的文件流並讓其他東西在不崩潰的情況下運行。

我正在打掃一箇舊的項目,需要限制上傳的文件,使他們只有圖像文件,沒有什麼邪惡的。

此代碼總是給我一個錯誤消息不管是什麼

$imageinfo = getimagesize($_FILES['bf_file'][$key]['tmp_name']); 
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg') { 
alert ("Sorry, we only accept GIF and JPEG images"); 
exit; 
} 

這裏是黑名單努力

$blacklist = array(".php", ".phtml", ".php3", ".php4", ".js", ".shtml", ".pl" ,".py" 
,".txt", ".doc"); 

foreach ($blacklist as $file) 
{ 
if(preg_match("/$file\$/i", $_FILES['bf_file'][$key]['tmp_name'])) 
{ 
alert "ERROR: Uploading executable files Not Allowed\n"; 
exit(); 
} 
} 

這裏是另一個和getimagesize

$size = getimagesize($_FILES[bf_file][$key][tmp_name]); 
$fp = fopen($_FILES[bf_file][$key][tmp_name], "rb"); 
if ($size && $fp) { 
header("Content-type: {$size['mime']}"); 
fpassthru($fp); 
continue; 
} else 
// error 
alert("Inappropriate file type"); 

關於這些無論文件是否上傳,我都會收到錯誤消息。

我只需要將這些控件放置在我的文件的某個位置,以便如果上傳的文件通過檢查,則所有內容都會作爲上傳器傳遞,其他所有內容都可以正常工作,但不具備這些限制器和檢查的好處。

此外,用戶不應該被要求上傳文件。有3個字段,主題,正文和文件上傳。只有主體和身體需要有數據並且現在可以工作。

任何幫助將不勝感激。

感謝,

詹姆斯

+3

'$ key'的值是什麼?無論它包含什麼內容,由於很久以前某些PHP作者的某些*高級*愚蠢,您需要引用'$ _FILES ['bf_file'] ['tmp_name'] [$ key]'而不是$ _FILES ['bf_file'] [$ key] ['tmp_name']'。另外請注意,'getimagesize()'是唯一明智的方法,我甚至無法在評論給我的少量空間中解釋你的黑名單方法是錯誤的。 – DaveRandom 2012-04-24 15:39:07

+1

這裏有一個:你的preg_match不是多行的,所以很容易受到空白的攻擊。使用白名單的原因之一,而不是黑名單。另外,您確實需要從圖像畫布中複製像素數據,但如果您僅保存文件,則容易受到惡意用戶上載包含嵌入式服務器端腳本的圖像文件的影響。 – Cheekysoft 2012-04-24 16:10:29

+0

@Cheekysoft,還有'index.php5'(它可能存在)和'index.php.fr'([content negotiation](http://httpd.apache.org/docs/current/content-negotiation.html) ) – xfix 2012-04-24 16:14:43

回答

1

你的腳本是所有的地方例如

$imageinfo = getimagesize($_FILES['bf_file'][$key]['tmp_name']); 

要獲得臨時名稱應該是$_FILES['bf_file']['tmp_name'][$key]而且文件大小是通過$_FILES['bf_file']['size'][$key]

已經返回你爲什麼不看看類似問題的詳細例子

multi image upload wrong quantity on file-upload

Uploading images with the help of arrays and fetch errors

+0

很明顯,我只是環顧四周,從網上抓取這些代碼,並將它們扔到我的頁面中。談論$ key的位置,這是因爲有多張圖片可以上傳?謝謝 – crazytrain999 2012-04-24 16:33:17

+0

不客氣..點擊鏈接有詳細的例子之前已經做了...和它的字符串非常f .. ..你不應該有定製它的問題 – Baba 2012-04-24 16:34:37

1

在第一片段。那麼,getimagesize()實際上會返回MIME類型(與Baba所說的相反),但是您不應該依賴它。完全有可能在開頭看起來像 PNG GIF(任何阻止PNG的原因?),但在標題後有<?php dangerous_code(); ?>。另外,我不知道你用[$key]在試着什麼。我不知道它是什麼,陣列看起來像$_FILES[$form_name][$file_field](例如$_FILES['file_input']['tmp_size']。沒有第三個字段。除非你正在做多個文件上傳,然後看看巴巴說什麼(這是非常hacky功能)。接下來,PHP不'你的意思是echo

在第二個片段中,我看到你正在做錯誤的東西,Dot是正則表達式中的元字符,但在這種情況下,它並不重要。無論如何,黑名單方法存在缺陷,因爲您不知道您的服務器是否支持.php5擴展名。即使它沒有,有人可以通過使文件hack.php.fr(Apache認爲.fr是語言)濫用content negotiation在Apache中。你的方法有缺陷 - 只要給PNG文件.png擴展名,無論原始擴展名是什麼等等。

在第三個例子中,你激活了錯誤的變量 - 但也使用了barewords(你不應該,雖然我知道你應該有常量大寫(所以與PHP所說的相反,如果你的裸語不那麼危險有常識),它們極其緩慢,比正常字符串慢,如果你有E_NOTICE(提示:你應該))會犯很多錯誤。接下來,continue不適用於if條件 - 它適用於循環條件(它也適用於switch(作爲break),但我想這只是爲了一致性)。

至於沒有上傳文件,這很容易。只要在isset($_FILES['file_input_name'])附近做條件。

TL;博士 - 瞭解PHP正確

+0

'那麼違反PHP說的,裸語不那麼危險如果你有常識 - 公平點,但他們仍然使你的錯誤日誌雜亂無章,容易發生錯誤。 – DaveRandom 2012-04-24 16:14:07

+0

@DaveRandom:已更新 – xfix 2012-04-24 16:15:49

+0

+1關於啞劇澄清 – Baba 2012-04-24 16:37:00

0

迄今爲止最安全的做法是防止你的服務器在用戶可以上傳文件夾完全執行動態的東西。然後,他們上傳的內容無關緊要。

包含php_flag engine off的上傳目錄中的.htaccess文件將阻止php。無論如何,其他可執行的東西應該被默認禁用,但你一定要檢查。