SQL Injection 是一個寫 PHP 時大家常常忘掉的問題,但是一忘掉就會讓駭客有機可乘。
用 PHP 做登入時,SQL 語法大概會長這樣:
select * from member where ID = '$USER_ID' and password = '$PASSWORD'
其中錢字號的是 PHP 的變數。登入時使用者填「test」、密碼填「123」,則 SQL 語法會變成下面這樣:
select * from member where ID = 'test' and password = '123'
不過萬一有人要惡作劇,使用者填「test」、密碼填「’ or ”=’」,則 SQL 語法就會變成下面這樣:
select * from member where ID = 'test' and password = '' or ''=''
看出來了嗎?如果把顏色去掉,最後一個判斷式是「or ”=”」,而這個判斷永遠會成立,所以即使前面沒有密碼也有資料會被列出來。這是最簡單的 SQL Injection,如果駭客心狠手辣的話,還能夠將機密資料列出、修改資料,甚至直接將資料庫刪除,所以不小心不行。如果有興趣的話可以參考以下相關網頁:
資安論壇 :: 觀看文章 – SQL Injection之解決建議措施及相關資訊彙整
http://forum.icst.org.tw/phpBB2/viewtopic.php?t=4376
SQL Injection WhitePaper
http://www.spidynamics.com/whitepapers/WhitepaperSQLInjection.pdf
PHP 5 有提供 magic quote 會自動將單引號、雙引號加上反斜線,網路上也有寫好的程式可以使用,像是我之前寫的「PHP avoid SQL Injection 2」,但事實上這樣還是不夠的。
SQL 語法中,欄位的資料型態會有不同的語法,像說 SerialNumber = 123 和 UserName = ‘zero’,就有單引號的差別,如果 PHP 讀取欄位資料後沒有特別去注意資料型態,可能就會發生 SQL 語法中字串沒有使用引號的錯誤,丟出錯誤訊息一樣很危險。所以在開始使用變數時,最好做資料型態的轉換或是辨認,以免發生意想不到的狀況。
想要試試看自己的網頁有沒有上述的漏洞,可以使用 Parosproxy 這套漏洞檢測軟體做測試,他會再抓取所有可以使用的網頁連結以後,對每個網頁進行特定的檢測。
首先要先設定瀏覽器的 proxy 設定,讓瀏覽器透過 Paros 來上網,設定如下:
接下來把 Paros 啟動,然後讓瀏覽器瀏覽你準備要測試的網頁,這樣 Paros 就會抓到網頁位置,抓到以後就可以準備掃瞄。
在上面的清單中,選擇要掃瞄的網站以後,點選功能表的 Analyse -> Spider,抓取整個網站所有的超連結。
抓取後左下方應該會出現網站內的超連結列表,Paros 之後就針對這幾個連結進行漏洞測試。準備好開始測試後,點選 Analyse -> Scan 即可。
待掃瞄結束後,左下角 alert 頁籤中會顯示出你網站有漏洞的網頁,以及漏洞的類型,但是並不是有顯示就表示一定有漏洞,也不表示找不到漏洞就絕對安全,請自行判斷掃瞄結果。
掃瞄結束後,記得把瀏覽器的 proxy 設定改回來,不然 Paros 關掉以後就不能上網了。