檔案名字處理
檔案名字得看業務要求。不需要保留原始名字,則隨機生成名字,拼接上白名單校驗過的字尾即可。【推薦學習:】
反之要謹慎處理:
//允許上傳的字尾白名單
$extension_white_list = ['jpg', 'pdf'];
//原始檔案的名字
$origin_file_name = 'xx/xxx/10月CPI同比上漲2.1%.php.pdf';
//提取檔案字尾,並校驗是否在白名單內
$extension = strtolower(pathinfo($origin_file_name, PATHINFO_EXTENSION));
if (!in_array($extension, $extension_white_list)) {
die('錯誤的檔案型別');
}
//提取檔名
$new_file_name = pathinfo($origin_file_name, PATHINFO_BASENAME);
//擷取掉字尾部分
$new_file_name = mb_substr($new_file_name, 0, mb_strlen($new_file_name) - 1 - mb_strlen($extension));
//只保留有限長度的名字
$new_file_name = mb_substr($new_file_name, 0, 20);
//替換掉所有的 . 避免攻擊者構造多字尾的檔案,缺點是檔名不能包含 .
$new_file_name = str_replace('.', '_', $new_file_name);
//把處理過的名字和字尾拼接起來構造成一個名字
$new_file_name = $new_file_name . '.' . $extension;
print_r($new_file_name); //10月CPI同比上漲2_1%_php.pdf
登入後複製
檔案內容處理
檔案字尾只是表面,一個 php 檔案,把字尾改成 jpg,也改變不了它攜帶 php 程式碼的事實。
針對圖片檔案,可以讀取圖片檔案頭判斷圖片型別,當然我也沒測試過這個方法,感興趣的可以自測。
另外即便上述方法可行,依然可以繞過,只要在 php 檔案的頭部寫入某個圖片型別的頭部特徵的位元組即可偽裝。
針對圖片檔案內容處理,真正的大招是重繪圖片。
windows 系統下用 copy 命令可以製作一個包含 php 程式碼的圖片檔案,命令如下:
Copy 1.jpg/b + test.php/a 2.jpg
登入後複製
上述命令的意思是,把 test.php 合併到 1.jpg 的尾部,並重新匯出到 2.jpg 裡面,如此一來,這個 2.jpg 就是一個包含 php 程式碼的圖片檔案,可以用記事本開啟它,拖卷軸到底部看到 php 程式碼。
像這種不乾淨的圖片,用重繪圖片的方式可以剔除掉不乾淨的部分。下面是重繪圖片的 php 程式碼:
try {
$jpg = '包含php程式碼的.jpg';
list($width, $height) = getimagesize($jpg);
$im = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($jpg);
imagecopyresampled($im, $image, 0, 0, 0, 0, $width, $height, $width, $height);
$target = '重繪後乾淨的圖片.jpg';
imagejpeg($image, $target);
} finally {
isset($im) && is_resource($im) && imagedestroy($im);
isset($image) && is_resource($image) && imagedestroy($image);
}
登入後複製
這個處理辦法的缺點是,耗費記憶體,圖片失真,而且只能處理圖片。
當然其它的檔案格式,我也不知道能不能用重繪的思路去處理。
檔案許可權處理
只討論 Linux 下的許可權,先簡單介紹 Linux 的許可權:
讀取,字母 r 或數位 4 表示
寫入,字母 w 或數位 2 表示
執行,字母 x 或數位 1 表示
登入後複製
對檔案來講,rwx 是如下含義:
r:可開啟讀取此檔案
w:可寫入此檔案
x:可執行此檔案
登入後複製
對目錄來講,rwx 的含義又有點差別:
r:可讀取此目錄的內容列表
w:可在此目錄裡面進行:增、刪、改檔案和子目錄
x:可進入此目錄
登入後複製
另外 Linux 裡面,針對一個檔案,使用者是會被分成三種,分別是:建立該檔案的使用者、和建立該檔案的使用者處於同一使用者組的使用者、既不是建立者也不是同一個小組的其它使用者。
有了對 Linux 的許可權瞭解,針對上傳的檔案所在的目錄,應該設定 755 許可權,表示:
建立該目錄的使用者有讀取、寫入、進入此目錄的許可權
和建立該目錄的使用者處於同一使用者組的使用者有讀取、進入此目錄的許可權
既不是建立者也不是同一個小組的其它使用者有讀取、進入此目錄的許可權
755 的許可權設定,可以讓 nginx 代理靜態檔案的時候不會報 403 錯誤。
程式碼範例:
mkdir($save_path, 0755, true);
登入後複製
針對上傳的檔案,採用更嚴格的許可權設定,應該設定 644 許可權,表示:
建立該檔案的使用者有讀取、寫入此檔案的許可權,無法執行
和建立該檔案的使用者處於同一使用者組的使用者只有讀取許可權
既不是建立者也不是同一個小組的其它使用者只有讀取許可權
644 的許可權設定,可以確保即便是上傳了一個非法檔案也無法串改內容、執行。
程式碼範例:
chmod($file, 0644);
登入後複製
檔案伺服器處理
掏錢買個 oss 儲存服務吧,啥雞毛都不考慮了,直接丟上去。
原文地址:https://learnku.com/articles/73100
作者部落格:https://learnku.com/blog/buexplain
php入門到就業線上直播課:
以上就是PHP檔案上傳處理邏輯大梳理(全面分析)的詳細內容,更多請關注TW511.COM其它相關文章!