自己了解php中sql注入一些方法介紹,下面介紹的全部是最常見(jiàn)的sql注入方法了,有需要的朋友可參考一下.
1,何為注入?比如我們?cè)诓樵償?shù)據(jù)庫(kù)的時(shí)候,我們通過(guò)文章的id號(hào)來(lái)取出這篇文章的所有信息,那么SQL語(yǔ)句可以這樣寫(xiě):select * from blog where id=5 ,id的值通過(guò)用戶的操作來(lái)傳遞,一般是GET方式,形如read.php?id=5,這樣看起來(lái)是沒(méi)有任何問(wèn)題,但是如果我們稍微改下SQL語(yǔ)句,如下:
select * from blog where id=5 or 1=1
1=1這個(gè)是恒等的,那么這條語(yǔ)句就會(huì)取出所有的文章,要修改這個(gè)只需要改一下GET的傳值即可:read.php?id='5 or 1=1';注意這兩個(gè)單引號(hào)...所以最簡(jiǎn)單的就是我們可以通過(guò)直接把參數(shù)改為單引號(hào)來(lái)查看這個(gè)鏈接是否存在注入,當(dāng)然,非法用戶看到所有的文章并不要緊,但是如果這個(gè)表是保存賬號(hào)和密碼的呢?
2.如何防范注入?
說(shuō)到底,防范注入的根本就在于字符的過(guò)濾,因?yàn)榉欠ㄓ脩粢话愣际峭ㄟ^(guò)構(gòu)造URL來(lái)傳值的,如果我們過(guò)濾了他傳進(jìn)來(lái)的非法參數(shù),這非法的SQL語(yǔ)句就不會(huì)執(zhí)行,那么我們也就防止網(wǎng)站被注入.
PHP內(nèi)置的過(guò)濾字符串還是相當(dāng)不錯(cuò)的,先看看具體代碼,代碼如下:
- function safe($s)
- {
- if(!get_magic_quotes_gpc())
- {
- if(is_array($s))
- foreach($s as $key=>$value)
- $s[$key] = addslashes($value);
- else
- $s=addslashes($s);
- }
- return $s;
- }
- function html_safe($s)
- //開(kāi)源代碼Vevb.com
- {
- return nl2br(htmlspecialchars(safe($s) )) ;
- }
如果你不知道上面用到的幾個(gè)內(nèi)置函數(shù),也懶了去查手冊(cè)的話,那我就說(shuō)下這幾個(gè)函數(shù):
magic_quotes_gpc這個(gè)稱為魔術(shù)引號(hào),如果這個(gè)功能開(kāi)啟,那么當(dāng)向數(shù)據(jù)庫(kù)中插入數(shù)據(jù)時(shí),魔術(shù)引號(hào)所做的就是自動(dòng)對(duì)所有的 GET、POST、COOKIE 數(shù)據(jù)運(yùn)用 addslashes() 函數(shù)。get_magic_quotes_gpc()就是用來(lái)獲取服務(wù)器上這個(gè)功能是否開(kāi)啟的:如果開(kāi)啟了,那么直接返回?cái)?shù)據(jù);如果沒(méi)開(kāi)啟,那么手動(dòng)對(duì)參數(shù)進(jìn)行addslashes()轉(zhuǎn)義。這樣就可以防止雙層轉(zhuǎn)義~
addslashes -- 使用反斜線引用字符串,描述:string addslashes ( string str );返回字符串,該字符串為了數(shù)據(jù)庫(kù)查詢語(yǔ)句等的需要在某些字符前加上了反斜線。這些字符是單引號(hào)(')、雙引號(hào)(")、反斜線()與 NUL(NULL 字符)。 一個(gè)使用 addslashes() 的例子是當(dāng)你要往數(shù)據(jù)庫(kù)中輸入數(shù)據(jù)時(shí)。例如,將名字 O'reilly 插入到數(shù)據(jù)庫(kù)中,這就需要對(duì)其進(jìn)行轉(zhuǎn)義。大多數(shù)據(jù)庫(kù)使用 作為轉(zhuǎn)義符:O'reilly。這樣可以將數(shù)據(jù)放入數(shù)據(jù)庫(kù)中,而不會(huì)插入額外的,當(dāng) PHP 指令 magic_quotes_sybase 被設(shè)置成 on 時(shí),意味著插入 ' 時(shí)將使用 ' 進(jìn)行轉(zhuǎn)義。
下面的那個(gè)htmlspecialchars就是對(duì)Html中的字符進(jìn)行轉(zhuǎn)換,比如說(shuō)將‘&’轉(zhuǎn)成‘&’,將‘<’轉(zhuǎn)成‘<’,nl2br這個(gè)是將回車(chē)換行轉(zhuǎn)換成<br/>,這個(gè)在用戶輸入評(píng)論之類的信息時(shí)候用得比較多。
通過(guò)上面的幾個(gè)函數(shù),我們已經(jīng)可以過(guò)濾一些簡(jiǎn)單的注入了,另外再說(shuō)幾個(gè)小的方面:對(duì)于最開(kāi)始的那個(gè)例子,實(shí)際上改進(jìn)的地方很多,比如寫(xiě)成這樣看起來(lái)應(yīng)該更規(guī)范一些,代碼如下:
SELECT * FROM `blog` WHERE `id`='$id'
對(duì)于SQL的關(guān)鍵字我們用大寫(xiě)來(lái)表示,對(duì)于數(shù)據(jù)庫(kù)中的表和字段我們用小寫(xiě),另外在字段名和表名上加上“·”這個(gè)符號(hào)(鍵盤(pán)上數(shù)字1左邊的那個(gè)鍵上),并且在進(jìn)來(lái)的id上我們用單引號(hào)引起來(lái),對(duì)于這樣的傳進(jìn)來(lái)參數(shù)是數(shù)字類型的,我們可以對(duì)$_GET到的值進(jìn)行強(qiáng)制轉(zhuǎn)換,但我更習(xí)慣這樣:
- $id = $_GET['id']*1; //獲取文章的id,用來(lái)顯示文章信息
- //開(kāi)源代碼Vevb.com
- if($id == 0){
- echo "ERROR...";
- exit();
- }
如果一發(fā)現(xiàn)傳進(jìn)來(lái)的不是數(shù)字,那么很大可能性性是存在問(wèn)題的參數(shù),那么我們直接給出錯(cuò)誤提示然后退出就行,這樣再省得再去給非法用戶執(zhí)行數(shù)據(jù)庫(kù)查詢操作了.
最后我們看一下JBlog中的一個(gè)處理注入的地方,includecommon.php的38行,代碼如下:
- if ( !get_magic_quotes_gpc() ) {
- $_GET = add_slashes($_GET);
- $_POST = add_slashes($_POST);
- $_COOKIE = add_slashes($_COOKIE);
- }
includefunc_global.php的194行,代碼如下:
- //addslashes
- function add_slashes($string) {
- if (!is_array($string)) return addslashes($string);
- foreach ($string as $key => $val) {
- $string[$key] = add_slashes($val);
- }
- return $string;
- }
當(dāng)然,這應(yīng)該只是一部分,其他的應(yīng)該也大同小異.
新聞熱點(diǎn)
疑難解答