1.簡單sql防注入
所謂SQL注入式攻擊,就是攻擊者把SQL命令插入到Web表單的輸入域或頁面請求的查詢字符串,欺騙服務器執行惡意的SQL命令。
在某些表單中,用戶輸入的內容直接用來構造(或者影響)動態SQL命令,或作爲存儲過程的輸入參數,這類表單特別容易受到SQL注入式攻擊。
magic_quotes_gpc的一點認識 以及addslashes addcslashes區別:
1、條件: magic_quotes_gpc=off
寫入數據庫的字符串未經過任何過濾處理。從數據庫讀出的字符串也未作任何處理。
數據: $data=”snow\'\'\'\'sun” ; (snow和sun之間是四個連續的單引號).
操作: 將字符串:”snow\'\'\'\'sun” 寫入數據庫,
結果: 出現sql語句錯誤,mysql不能順利完成sql語句,寫入數據庫失敗。
數據庫保存格式:無數據。
輸出數據格式:無數據。
2、條件: magic_quotes_gpc=off
寫入數據庫的字符串經過函數addslashes()處理。從數據庫讀出的字符串未作任何處理。
數據: $data=”snow\'\'\'\'sun” ; (snow和sun之間是四個連續的單引號)
操作: 將字符串:”snow\'\'\'\'sun” 寫入數據庫
結果: sql語句順利執行,數據成功寫入數據庫
數據庫保存格式:snow\'\'\'\'sun (和輸入一樣)
輸出數據格式:snow\'\'\'\'sun (和輸入一樣)
說明: addslashes()函數將單引號轉換爲\\\'的轉義字符使sql語句成功執行,但\\\'並未作爲數據存入數據庫,數據庫保存的是snow\'\'\'\'sun 而並不是我們想象的snow\\\'\\\'\\\'\\\'sun
說明: 對於未經處理的單引號在寫入數據庫時會使sql語句發生錯誤
3、條件: magic_quotes_gpc=on
寫入數據庫的字符串未經過任何處理。從數據庫讀出的字符串未作任何處理。
數據: $data=”snow\'\'\'\'sun” ; (snow和sun之間是四個連續的單引號)
操作: 將字符串:”snow\'\'\'\'sun” 寫入數據庫
結果: sql語句順利執行,數據成功寫入數據庫
數據庫保存格式:snow\'\'\'\'sun (和輸入一樣)
輸出數據格式:snow\'\'\'\'sun (和輸入一樣)
說明: magic_quotes_gpc=on 將單引號轉換爲\\\'的轉義字符使sql語句成功執行,但\\\'並未作爲數據入數據庫,數據庫保存的是snow\'\'\'\'sun而並不是我們想象的snow\\\'\\\'\\\'\\\'sun。
4、條件: magic_quotes_gpc=on
寫入數據庫的字符串經過函數addlashes()處理。從數據庫讀出的字符串未作任何處理。
數據: $data=”snow\'\'\'\'sun” ; (snow和sun之間是四個連續的單引號)
操作: 將字符串:”snow\'\'\'\'sun” 寫入數據庫
結果: sql語句順利執行,數據成功寫入數據庫
數據庫保存格式:snow\\\'\\\'\\\'\\\'sun (添加了轉義字符)
輸出數據格式:snow\\\'\\\'\\\'\\\'sun (添加了轉義字符)
說明: magic_quotes_gpc=on 將單引號轉換爲\\\'的轉義字符使sql語句成功執行addslashes又將即將寫入數據庫的單引號轉換爲\\\',後者的轉換被作爲數據寫入數據庫,數據庫保存的是snow\\\'\\\'\\\'\\\'sun
總結如下:
1、對於magic_quotes_gpc=on的情況
我們可以不對輸入和輸出數據庫的字符串數據做addslashes()和stripslashes()的操作,數據也會正常顯示。如果此時你對輸入的數據作了addslashes()處理,那麼在輸出的時候就必須使用stripslashes()去掉多餘的反斜槓。
2、對於magic_quotes_gpc=off 的情況
必須使用addslashes()對輸入數據進行處理,但並不需要使用stripslashes()格式化輸出因爲addslashes()並未將反斜槓一起寫入數據庫,只是幫助mysql完成了sql語句的執行。
補充:
magic_quotes_gpc 作用範圍是:WEB客戶服務端;作用時間:請求開始時,例如當腳本運行時。magic_quotes_runtime 作用範圍:從文件中讀取的數據或執行exec()的結果或是從SQL查詢中得到的;作用時間:每次當腳本訪問運行狀態中產生的數據。
另外:
addslashes()函數的作用是爲字符串裏面的部分字符添加反斜線轉義字符,addslashes()函數只爲4個字符添加轉義,單引號“’ ”,雙引號“””,反斜線“\\”和NULL(“\\0”)。
addcslashes()函數的作用也是對字符串添加轉義,但是轉義的字符必須由第二個參數指定,第二個參數的使用方法難度太高,跳過不講。
stripslashes()函數的作用和addslashes()函數正好相反,可以將 addslashes()函數轉義的那4個字符取消轉義。
同樣,stripcslashes()函數的作用和addcslashes()函數相反。
quotemeta()函數的作用是對11個特定字符進行轉義,包括:. \\ + * ? [ ^ ] ( $ ) 似乎是可以用在正則裏面。
echo addslashes(\"\'\\\"\\ \");
// 顯示 \\\'\\\"\\\\
echo addcslashes(\"zoo[\'.\']\", \'zo\');
// 顯示 \\z\\o\\o[\'.\']
echo addcslashes(\"z\\\"oo[\'.\']\", \'\\\'\\\"\');
// 顯示 z\\\"oo[\\\'.\\\']
echo addcslashes(\'foo[ ]\', \'A..z\');
// 顯示 \\f\\o\\o\\[ \\]
echo stripslashes(addslashes(\"\'\\\"\\ \"));
// 顯示 \'\"\\
echo stripcslashes(addcslashes(\"z\\\"oo[\'.\']\", \'\\\'\\\"\'));
// 顯示 z\"oo[\'.\']
echo quotemeta(\". \\ + * ?\");
// 顯示 \\. \\\\ \\+ \\* \\?
補充:
get_magic_quotes_gpc
取得 PHP 環境變量 magic_quotes_gpc 的值。
語法: long get_magic_quotes_gpc(void);
返回值: 返回 0 表示關閉本功能;
返回 1 表示本功能打開。
當 magic_quotes_gpc 打開時,所有的 ' (單引號), " (雙引號), \ (反斜線) and 空字符會自動轉爲含有反斜線的轉義字符。
解決方案,檢查用戶提交的值的類型:
從前面的討論中我們看到,迄今爲止,SQL注入的主要來源往往出在一個意料之外的表單入口上。然而,當你經由一個表單向用戶提供機會提交某些值時,你應該有相當的優勢來確定你想取得什麼樣的輸入內容-這可以使得我們比較容易地檢查用戶入口的有效性。
在以前的文章中,我們已經討論過這樣的校驗問題;所以,在此,我們僅簡單地總結當時我們討論的要點。
如果你正在期望一個數字,那麼你可以使用下面這些技術之一來確保你得到的真正是一個數字類型:
· 使用is_int()函數(或is_integer()或is_long())。
· 使用gettype()函數。
· 使用intval()函數。
· 使用settype()函數。
爲了檢查用戶輸入內容的長度,你可以使用strlen()函數。爲了檢查一個期望的時間或日期是否有效,你可以使用strtotime()函數。它幾乎一定能夠確保一位用戶的入口中沒有包含分號字符(除非標點符號可以被合法地包括在內)。你可以藉助於strpos()函數容易地實現這一點,如下所示:
if( strpos( $variety, ';' ) ) exit ( "$variety is an invalid value for variety!" );
正如我們在前面所提到的,只要你仔細分析你的用戶輸入期望,那麼,你應該能夠很容易地檢查出其中存在的許多問題。
從你的查詢中濾去每一個可疑字符 。儘管在以前的文章中,我們已經討論過如何過濾掉危險字符的問題;但是在此,還是讓我們再次簡單地強調並歸納一下這個問題:
· 不要使用magic_quotes_gpc指令或它的"幕後搭擋"-addslashes()函數,此函數在應用程序開發中是被限制使用的,並且此函數還要求使用額外的步驟-使用stripslashes()函數。
· 相比之下,mysql_real_escape_string()函數更爲常用,但是也有它自己的缺點。
mysql_real_escape_string — 轉義 SQL 語句中使用的字符串中的特殊字符,並考慮到連接的當前字符集。
區別:
addslashes() 是強行加;
mysql_real_escape_string() 會判斷字符集,但是對PHP版本有要求;
mysql_escape_string不考慮連接的當前字符集。
更多信息,請關注千鋒php,千鋒論壇。