2014-03-04 15 views
0

我的PHP Web應用程序解析傳入的電子郵件並將其存儲在MySQL表中。在解析電子郵件內容後,我使用MySQL準備的語句來存儲不同的電子郵件部分,例如「收件人」,「發件人」,「主題」,「正文」等,以防止任何代碼注入。文件名是否可以注入代碼

如果電子郵件有附件,我需要將它存儲在一個文件夾中,並且如果它使用PGP加密以通過PGP EXEC功能運行gpg外部命令。

此文件的處理似乎是代碼的可注射的,即如果有人叫attahcment是這樣的:

「Mydoc.doc的mysqldump_to_www_root and_format_all_partitions」

也許我錯了。爲了防止這種情況,我決定來檢查文件是否存在它的創作一樣,右後:

//Here I save the file to a folder 
$filename = $attachment->filename; 
if ($fp = fopen($save_dir.$filename, 'w')) { 
    while($bytes = $attachment->read()) { 
     fwrite($fp, $bytes); 
    } 
    fclose($fp); 
} 

//Here I check for injection 
If(!is_file($attach_dir.'/'.$filename)) { 
    // something wrong, do not proceed 
} 

我的操作系統是Ubuntu的使用EXT4文件系統。這會不會讓我從電子郵件附件中的可能代碼注入中解脫出來?我是否需要擔心它擺在首位,如果最終我想做例如follwoing:

$cmd = "gpg --passphrase *** '$attachedir/$filename'"; 
exec($cmd, $output); 

換句話說沒有存儲文件到磁盤消毒/過濾文件名,或者有可能是例外?

+2

爲什麼不將文件名稱更改爲隨機字符串,並將原始名稱和隨機字符串存儲在數據庫中? –

+2

@ChrisForrence如果原始名稱含有不需要的代碼,該怎麼辦? – user164863

+0

然後不需要的代碼作爲數據庫表的「原始文件名」列中的字符串被無害地存儲。你說你正在使用準備好的語句來避免SQL注入,這是正確的做法。 – Wyzard

回答

1

PHP有一個escapeshellarg()函數,它在字符串中轉義shell元字符以確保它被視爲單個參數,而不是一組參數或單獨的命令。在構建傳遞給exec()的命令字符串時,在文件名上使用此名稱。

+0

如果我做$ cmd =「gpg --passphrase *** escapeshellarg('$ attachedir/$ filename')」; $ exec($ cmd,$ output)我得到一個錯誤,因爲escapeshellarg進入了gpg bash命令行:( – user164863

+0

沒錯,因爲那不是調用一個函數,它只是在字符串文字中寫下「escapeshellarg」這個單詞。 gpg --passphrase ****「。escapeshellarg($ attachedir。」/「$ filename)'。 – Wyzard

+0

謝謝你,你是對的!但它吃掉非ASCII字符,即如果我的俄文字母在文件名中跳過 – user164863

相關問題