腳本安全的本質(zhì)_PHP+MYSQL第3/3頁
更新時(shí)間:2008年10月03日 20:21:00 作者:
從代碼級(jí)別上,也就是應(yīng)用層次上考慮代碼安全的話(也就是不考慮底層的語言本身等問題的漏洞),腳本安全問題就是函數(shù)和變量的問題。
二 哪里是不安全的
變量最終是要代碼處理的,代碼最終是要依靠一些系統(tǒng)的函數(shù)和語句執(zhí)行的,不正確的變量出現(xiàn)在危險(xiǎn)的函數(shù)里,那么恭喜你,漏洞出現(xiàn)了!
1 Sql注射漏洞:按照我們的理解,就是Sql函數(shù)里出現(xiàn)了不安全的變量,在php中執(zhí)行這樣的語句在系統(tǒng)中是很多的,在Dz的初始化文件中有如下代碼:
if($sid) {
if($discuz_uid) {
$query = $db->query("SELECT s.sid, s.styleid, s.groupid='6' AS ipbanned, s.pageviews AS spageviews, s.lastolupdate, s.seccode, m.uid AS discuz_uid,
m.username AS discuz_user, m.password AS discuz_pw, m.secques AS discuz_secques, m.adminid, m.groupid, m.groupexpiry,
m.extgroupids, m.email, m.timeoffset, m.tpp, m.ppp, m.posts, m.digestposts, m.oltime, m.pageviews, m.credits, m.extcredits1, m.extcredits2, m.extcredits3,
m.extcredits4, m.extcredits5, m.extcredits6, m.extcredits7, m.extcredits8, m.timeformat, m.dateformat, m.pmsound,
m.sigstatus, m.invisible, m.lastvisit, m.lastactivity, m.lastpost, m.newpm, m.accessmasks,m.xspacestatus, m.editormode, m.customshow
FROM {$tablepre}sessions s, {$tablepre}members m
WHERE m.uid=s.uid AND s.sid='$sid' AND CONCAT_WS('.',s.ip1,s.ip2,s.ip3,s.ip4)='$onlineip' AND m.uid='$discuz_uid'
AND m.password='$discuz_pw' AND m.secques='$discuz_secques'");
} else {
$query = $db->query("SELECT sid, uid AS sessionuid, groupid, groupid='6' AS ipbanned, pageviews AS spageviews, styleid, lastolupdate, seccode
FROM {$tablepre}sessions WHERE sid='$sid' AND CONCAT_WS('.',ip1,ip2,ip3,ip4)='$onlineip'");
找下$db->query函數(shù)中的美圓符號(hào)吧,呵呵,發(fā)現(xiàn)有好幾個(gè),也就是說可能存在漏洞了,注意,說的是可能,因?yàn)楝F(xiàn)在的代碼安全性都有提高,找個(gè)沒人管的變量不容易啊,一般的變量都會(huì)正確的初試化,但是跟蹤$onlineip變量就可以發(fā)現(xiàn)這個(gè)變量基本沒有管的,因?yàn)檫@個(gè)是從Http頭里提取的,一般的人不怎么會(huì)注意這個(gè),但是偏偏問題出現(xiàn)了:)
需要說明的是,函數(shù)產(chǎn)生漏洞,而不管語句是什么,所以只要是update或者 insert或者是select里出現(xiàn)了變量,該變量是我們可以控制的,并且改變量能突破程序的一些限制(什么限制我們后面會(huì)講到)從而控制這個(gè)sql語句的執(zhí)行,那么我們的漏洞就是成立的,能不能利用就要看具體環(huán)境了
2 Xss跨站腳本攻擊漏洞:這個(gè)漏洞其根本就是客戶端的Html注射漏洞,如果用戶提交變量里含有<>或者能被解釋成Html的字符被送到數(shù)據(jù)庫,然后再從數(shù)據(jù)庫輸出到瀏覽者的瀏覽器,那么就可能存在Xss注射漏洞。<>字符能導(dǎo)致跨站腳本攻擊很好理解,但是要注意的是不需要提交<>一樣會(huì)有這種問題,這是很多人所誤解的。假設(shè)我們的輸入如一個(gè)url最終是放在一個(gè)Html標(biāo)簽之內(nèi)的,這樣的情況很多,因?yàn)橛脩舻念^像什么的就必須這樣的形式:
echo "<img src=\"$url\">"
我們控制了img的屬性從也一樣實(shí)現(xiàn)了跨站腳本攻擊。
3 文件包含漏洞:這個(gè)主要是因?yàn)槲募瘮?shù)include與require等函數(shù)的參數(shù)中沒有做好限制,導(dǎo)致用戶能指定需要包含的文件如如下的代碼:
require_once ROOT_PATH."cache/style/$cssname.php";
如果我們能控制$cssname就可以控制需要包含的內(nèi)容,漏洞的存在就取決于這個(gè)變量可不可以控制了,如果可以控制又可以用到../跳轉(zhuǎn)的話,那么:)至于危害,也就是任意代碼執(zhí)行和目錄遍歷了。
4 直接寫入webshell漏洞:這在一些文本數(shù)據(jù)庫中見的很多,一些程序使用文本文件做為數(shù)據(jù)庫,于是不可避免的要用到如fopen,fread以及fwrite這些函數(shù),打開fopen函數(shù)的幫助看看:
resource fopen ( string filename, string mode [, bool use_include_path [, resource zcontext]] )
從這個(gè)幫助可以知道如果fopen函數(shù)的第一個(gè)參數(shù)可以控制就可能打開一些不應(yīng)該被打開的文件,其他的文件函數(shù)都是例似的,再次重申,變量的環(huán)境決定了它的價(jià)值:)
5 代碼執(zhí)行漏洞:能產(chǎn)生這種漏洞的一定要有這種功能的函數(shù),常見的有eval函數(shù)和preg_replace函數(shù),如果eval里出現(xiàn)了我們能控制的語句那么會(huì)產(chǎn)生問題,在preg_replace函數(shù)的第二個(gè)參數(shù)可能導(dǎo)致任意代碼執(zhí)行的問題!
6 絕對(duì)路徑泄露:這主要是由于php的報(bào)錯(cuò)造成的,使用一個(gè)不存在的文件,mysql查詢出錯(cuò),提交一個(gè)不符合類型的參數(shù)給一些函數(shù)都會(huì)導(dǎo)致這個(gè)問題,一般的程序都對(duì)函數(shù)的錯(cuò)誤用了@抑制,但是還是存在一些爆路徑的方法!有人說一個(gè)路徑不能代表什么,其實(shí)一個(gè)路徑可以知道操作系統(tǒng),知道路徑,可能知道虛擬主機(jī)的配置等等信息。、
7 邏輯混亂
如果一個(gè)變量用在了if等邏輯語句中,那么很可能導(dǎo)致邏輯混亂問題,跳過一些語句的執(zhí)行等等。
種種其他的函數(shù)出現(xiàn)的問題
三 過濾與饒過過濾
很多人已經(jīng)注意到了這些安全問題,php中也包含了自己的安全機(jī)制,那就是GPC=On的時(shí)候加入了對(duì)'和"以及\的轉(zhuǎn)義,很多的程序也都自己加入了這些轉(zhuǎn)義。其他腳本語言可能沒有這種機(jī)制,但是這種思路非常好。在被轉(zhuǎn)義的情況下,他可以保證用戶所有的輸入都是字符串,無論這個(gè)變量進(jìn)入哪里,包括sql查詢,跨站腳本等等,但是有個(gè)很重要的前提就是你所書寫的程序必須也把所有的輸入都當(dāng)作字符串來對(duì)待。很明顯,如果有以下的2個(gè)語句:
$query = $db->query("select * from user where uid=$id");
$query = $db->query("select * from user where uid='$id'");
哪個(gè)更安全一點(diǎn)呢?第一個(gè)語句做的假設(shè)是$id是數(shù)字類型變量,第二個(gè)假設(shè)輸入是字符類型變量所以使用''引用他。如果提交php?id=1 and 1=2對(duì)于第一個(gè)語句,最后變成:
select * from user where uid=1 and 1=2 //and 1=2成為了一個(gè)表達(dá)式
select * from user where uid='1 and 1=2' //and 1=2還是字符串的一部分
希望這個(gè)能給你一點(diǎn)提示,但不僅僅是sql注入!如果是跨站腳本漏洞的話,我們一樣可以使用上面的思路,無論用戶輸入什么,在過濾好<>,然后只要把用戶的輸入當(dāng)作一個(gè)字符串就行了,但是要注意,光一個(gè)轉(zhuǎn)義字符\'在html里很可能還是有'的意義,你需要去掉他在 html里的轉(zhuǎn)義,用htmlspecialchars()函數(shù),當(dāng)然也要配合程序安全的代碼,還是給兩個(gè)例子:
echo "<img src=htmlspecialchars($url)>";
echo "<img src='htmlspecialchars($url)'>";
哪個(gè)是沒有缺陷的呢?
上面的例子是在暗示,一個(gè)變量如果只能作為字符串,就是不要賦予它特定的含義,它是做不了什么的。那么你可能已經(jīng)想到了,對(duì)于上面提到的種種漏洞,如果迫不得已需要用戶控制變量,那么你只要過濾掉特殊意義的字符,然后把輸入只是作為一個(gè)字符串,那么就可以從代碼級(jí)別上杜絕這些漏洞了。譬如對(duì)于fopen函數(shù),只要我們過濾掉../以及..\這些字符,然后將用戶輸入的",'以及空字符等轉(zhuǎn)義就沒有問題了,對(duì)于寫webshell的問題可以通過如果是建立數(shù)據(jù)庫而已就可以轉(zhuǎn)義掉<>腳本標(biāo)記字符,如果產(chǎn)生的本身就是php文件那么可以將用戶的輸入限制在''或者在""之內(nèi),一切只是字符,跟跨站腳本的防御很相似吧!還有一些敏感字符可能是程序自己產(chǎn)生的,如下的代碼:
$deldb=explode("|",$imgdb['icon']);
就賦予了$imgdb['icon']神圣的意義,所以我們?cè)谔幚淼臅r(shí)候一定先要將 $imgdb['icon'] 里的|清干凈!
四 其他的問題
我上面所說的僅僅是在檢測漏洞與修補(bǔ)漏洞時(shí)的一些想法, 從函數(shù)著手分析變量的處理,但更多的時(shí)候程序的安全還是要依靠程序員清晰的思路的,但安全不僅僅是這樣,譬如GBK和Big5的編碼問題,還有上傳等問題。Php腳本是這樣,其他的腳本也是這樣
相關(guān)文章
php json轉(zhuǎn)換成數(shù)組形式代碼分享
這篇文章主要介紹了php json轉(zhuǎn)換成數(shù)組形式代碼分享,需要的朋友可以參考下2014-11-11php+mysql事務(wù)rollback&commit示例
執(zhí)行BEGIN之后,其作用同set autocommit=0,而且之后設(shè)置set autocommit=0或1時(shí)無效。所以,為使操作清楚,一般不使用BEGIN。2010-02-02PHP設(shè)置一邊執(zhí)行一邊輸出結(jié)果的代碼
這篇文章主要介紹了PHP中設(shè)置一邊執(zhí)行一邊輸出結(jié)果的實(shí)現(xiàn)代碼,需要的朋友可以參考下2013-09-09phpMyAdmin出現(xiàn)無法載入 mcrypt 擴(kuò)展,請(qǐng)檢查PHP配置的解決方法
出現(xiàn)以下幾種情況后可能會(huì)造成運(yùn)行phpmyadmin程序提示 無法載入 mcrypt 擴(kuò)展,請(qǐng)檢查 PHP 配置 的 錯(cuò)誤提示2012-03-03PHP類的自動(dòng)加載與命名空間用法實(shí)例分析
這篇文章主要介紹了PHP類的自動(dòng)加載與命名空間,結(jié)合實(shí)例形式分析了PHP類的自動(dòng)加載與命名空間相關(guān)概念、原理、用法與操作注意事項(xiàng),需要的朋友可以參考下2020-06-06PHP運(yùn)行SVN命令顯示某用戶的文件更新記錄的代碼
使用SVN開發(fā)者們平時(shí)開發(fā)或代碼上線過程中需要知道某個(gè)時(shí)間段內(nèi)修改或添加過那些文件,所以用PHP寫了個(gè)小程序,直接在瀏覽器中調(diào)用即可2014-01-01