如今基於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又被執行了