自己了解php中sql注入一些方法介紹,下面介紹的全部是最常見的sql注入方法了,有需要的朋友可參考一下。
何為注入?
比如我們在查詢數據庫的時候,我們通過文章的id號來取出這篇文章的所有信息。那麼SQL語句可以這樣寫:
代碼如下 復制代碼select * from blog where id=5
id的值通過用戶的操作來傳遞,一般是GET方式,形如read.php?id=5。這樣看起來是沒有任何問題,但是如果我們稍微改下SQL語句:
代碼如下 復制代碼select * from blog where id=5 or 1=1
1=1這個是恆等的,那麼這條語句就會取出所有的文章。要修改這個只需要改一下GET的傳值即可:read.php?id='5 or 1=1';注意這兩個單引號...所以最簡單的就是我們可以通過直接把參數改為單引號來查看這個鏈接是否存在注入。當然,非法用戶看到所有的文章並不要緊,但是如果這個表是保存賬號和密碼的呢?
2.如何防范注入?
說到底,防范注入的根本就在於字符的過濾,因為非法用戶一般都是通過構造URL來傳值的,如果我們過濾了他傳進來的非法參數,這非法的SQL語句就不會執行,那麼我們也就防止網站被注入!
PHP內置的過濾字符串還是相當不錯的,先看看具體代碼:
代碼如下 復制代碼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)
{
return nl2br(htmlspecialchars(safe($s) )) ;
}
如果你不知道上面用到的幾個內置函數,也懶了去查手冊的話,那我就說下這幾個函數:
magic_quotes_gpc這個稱為魔術引號,如果這個功能開啟,那麼當向數據庫中插入數據時,魔術引號所做的就是自動對所有的 GET、POST、COOKIE 數據運用 addslashes() 函數。get_magic_quotes_gpc()就是用來獲取服務器上這個功能是否開啟的:如果開啟了,那麼直接返回數據;如果沒開啟,那麼手動對參數進行addslashes()轉義。這樣就可以防止雙層轉義~
addslashes -- 使用反斜線引用字符串。描述:string addslashes ( string str );返回字符串,該字符串為了數據庫查詢語句等的需要在某些字符前加上了反斜線。這些字符是單引號(')、雙引號(")、反斜線()與 NUL(NULL 字符)。 一個使用 addslashes() 的例子是當你要往數據庫中輸入數據時。例如,將名字 O'reilly 插入到數據庫中,這就需要對其進行轉義。大多數據庫使用 作為轉義符:O'reilly。這樣可以將數據放入數據庫中,而不會插入額外的 。當 PHP 指令 magic_quotes_sybase 被設置成 on 時,意味著插入 ' 時將使用 ' 進行轉義。
下面的那個htmlspecialchars就是對Html中的字符進行轉換,比如說將‘&’轉成‘&’,,將‘<’轉成‘<’。nl2br這個是將回車換行轉換成<br/>,這個在用戶輸入評論之類的信息時候用得比較多。
通過上面的幾個函數,我們已經可以過濾一些簡單的注入了。另外再說幾個小的方面:
對於最開始的那個例子,實際上改進的地方很多,比如寫成這樣看起來應該更規范一些:
代碼如下 復制代碼SELECT * FROM `blog` WHERE `id`='$id'
對於SQL的關鍵字我們用大寫來表示,對於數據庫中的表和字段我們用小寫,另外在字段名和表名上加上“·”這個符號(鍵盤上數字1左邊的那個鍵上),並且在進來的id上我們用單引號引起來。
對於這樣的傳進來參數是數字類型的,我們可以對$_GET到的值進行強制轉換。但我更習慣這樣:
代碼如下 復制代碼$id = $_GET['id']*1; //獲取文章的id,用來顯示文章信息
if($id == 0){
echo "ERROR...";
exit();
}
如果一發現傳進來的不是數字,那麼很大可能性性是存在問題的參數,那麼我們直接給出錯誤提示然後退出就行,這樣再省得再去給非法用戶執行數據庫查詢操作了。
最後我們看一下JBlog中的一個處理注入的地方:
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;
}
當然,這應該只是一部分,其他的應該也大同小異。