如今基於PHP的WEB程式是越來越安全了,php.ini預設時的 magic_quotes_gpc=on就在初始安全性上提高了一個檔次.很多程式在接受到使用者的輸入時都會提前判斷一下 get_magic_quotes_gpc() 即使這個開關沒有開就馬上addslashes()函數跟上進行轉義,所以想在PHP程式中找到一個類似與以前ASP注入那樣的漏洞是比較不容易的.
對於PHP的跨站其實也很好防範,用 htmlentities() 就可以了,不過當處理XML檔案時採用這個函數可能會出現些問題,只需手工轉換下那5個元字元就可以了。舉個例子,以前寫過篇文章關於XML檔案隱患的,其實就是CDATA組件的問題,現在比較流行的說法是AJAX hacking,大概說下,看看以下代碼:
if ($rssid == 0 OR $rssid == 7) {
} elseif (!empty($stmt)) {
$dbinfo =& $db->getResultSet($stmt, array('pageSize'=>$pagesize));
if ($dbinfo === false) {
$msginfo = str_replace(']]>', ']]>', $lang['tpl.str0']);
$TPL_items .= <<<EOT
<item>
<title>{$msginfo}</title>
<link>{$fsetting['forumurl']}</link>
<author>{$fsetting['forumname']}</author>
<pubDate>{$datenow}</pubDate>
<description><![CDATA[{$msginfo}]]></description>
</item>
EOT;
$msginfo是使用者提交的,然後被程式寫進RSS裡以用來彙總,如果$msginfo的值為<sciript>alert('loveshell')</script>時,RSS彙總解析後會原樣輸出,如果為]]><sciript>alert('loveshell')</script>時,就可以跨站了,看看他的過濾:
if ($dbinfo === false) {
$msginfo = str_replace(']]>', ']]>', $lang['tpl.str0']);
很好意識到了這點,可是這句呢<title>{$msginfo}</title>,意識到問題所在很關鍵,重要的是要理解問題.
可是還是有很多會被程式員疏忽的地方,這是安全意識的問題,對於使用者的任何輸入,在寫程式時腦子裡都要提前做個思考:使用者的輸入是什麼類型的?使用者會有哪些輸入方式?怎麼處理使用者的錯誤和非常規輸入?
PHP的安全還體現在Safe Mode 和openbase-dir上.即使這樣基於PHP底層的一些漏洞還是會直接影響到這兩個非常重要的安全選項.舉個例子:
比如error_log() Safe Mode Bypass
看他的文法:bool error_log ( string message [, int message_type [, string destination [, string extra_headers]]] )
輸出錯誤資訊到一個檔案,可以這樣寫
<?
error_log("<? phpinfo();?>", 3, "test.php");
?>
運行在safe_mode關閉的情況下,直接存取test.php就可以看到phpinfo了,當safe_mode開的時候就會報錯,再這樣寫:
<?
error_log("<? phpinfo();?>", 3, "prefix://../../test.php");
?>
可以看到phpinfo又被執行了