在寫登錄注冊的時候發現了SQL和JS注入這個危害網站的用戶舉動:
測試方法:
SQL注入:
1 先來做一個測試: 2 用戶名:’ or 1 # 3 密碼:隨便寫8位以上 4 驗證碼:寫正確
好吧,就那么簡單就進去了:
概念
如果用戶在填寫表單或者其他數據的時候,通過一些特殊的數據形式,對SQL的行為作出了非法的影響,就叫作SQL注入!
基本原理
正常執行的sql語句:
1 select * from bg_admin where admin_name='zhouyang' and admin_pass=md5('12345678')
不正常執行的sql語句:
1 select * from bg_admin where admin_name='' or 1 #' and admin_pass=md5('123654uiykgjfhdsav')
拆分分析:
由於#在sql語句中是注釋符,所以,上面的SQL語句真正執行的是:
1 select * from bg_admin where admin_name='' or 1
很顯然,上面執行的結果就是where后面的條件永遠為真!其實就相當於:
1 select * from bg_admin
也就是說,只要bg_admin表中有正常的管理用戶,就可以查詢到數據!
其實,在這里可以進行sql注入的“用戶名”還有很多,比如:
‘ or 1 or ‘
1 select * from bg_admin where admin_name='' or 1 or '' and admin_pass=md5('ewsdfgbnvb')
特別強調:
1, 不僅僅是在用戶登錄的時候,SQL語句可以被注入,其他任何用戶的數據只要參與執行,都有可能被注入!
2, SQL注入的危害非常之大,有時候甚至可以刪除服務器上的整個數據庫:
比如:
用戶名為:' or 1;drop database php2010;#
注意:
MySQL數據庫默認的有information_schema,所有數據庫的名稱等信息都存放在里面,這些數據庫很容易獲取到默認數據庫的名字!
解決方案
1, 在業務邏輯上預防,比如要求用戶名只能由特定的字符組成(比如數字字母下划線)(使用正則表達式)
2, 使用PHP函數addslashes(最常用)
其中:
strip_tags(trim($data)是防止JS注入的!!
1 /** 2 * 對用戶的數據進行安全過濾 3 */ 4 protected function escapeData($data) { 5 return addslashes(strip_tags(trim($data))); 6 }
3, 使用MySQL提供的數據轉義函數:mysql_real_escape_string($data, $link);不過有一個前提是必須連接上數據庫之后才可以使用!
4, 使用預處理技術,因為預處理是強制將sql語句的結構和數據部分分開!