SQL注射原理

SQL注射原理

SQL 注射能使攻擊者繞過認證機制,完全控制遠程服務器上的數據庫。SQL是結構化查詢語言的簡稱,它是訪問數據庫的事實標準。目前,大多數Web應用都使用 SQL數據庫來存放應用程序的數據。幾乎所有的Web應用在後臺都使用某種SQL數據庫。跟大多數語言一樣,SQL語法允許數據庫命令和用戶數據混雜在一 起的。如果開發人員不細心的話,用戶數據就有可能被解釋成命令,這樣的話,遠程用戶就不僅能向Web應用輸入數據,而且還可以在數據庫上執行任意命令了。
登陸驗證
現 在以一個需要用戶身份認證的簡單的Web應用程序爲例進行講解。假定這個應用程序提供一個登錄頁面,要求用戶輸入用戶名和口令。用戶通過HTTP請求發送 他們的用戶名和口令,之後,Web應用程序檢查用戶傳遞來用戶名和口令跟數據庫中的用戶名和口令是否匹配。這種情況下,會要求在SQL數據庫中使用一個數 據庫表。
對一個用戶進行認證,實際上就是將用戶的輸入即用戶名和口令跟表中的各行進行比較,如果跟某行中的用戶名和口令跟用戶的輸入完全匹配,那麼該用戶就會通過認證。
假如後臺的sql語句時這樣拼接的
select id from test where username='"+myname+"' and password='"+mypasswd+"' ";
表面上看,如果用戶名和口令對匹配,那麼該用戶通過認證;否則,該用戶不會通過認證——但是,事實果真如此嗎?非也!讀者也許已經注意到了,這裏並沒有對SQL命令進行設防,所以攻擊者完全能夠在用戶名或者口令字段中注入SQL語句,從而改變SQL查詢 。爲此,我們仔細研究一下上面的SQL查詢字符串:
上述代碼認爲字符串username和password都是數據,不過,攻擊者卻可以隨心所欲地輸入任何字符 。如果一位攻擊者輸入的用戶名爲
’OR1=1—
而口令爲
x
雙劃符號--告訴SQL解析器,右邊的東西全部是註釋,所以不必理會。這樣,查詢字符串相當於:
select id from test where username='' or 1=1;
如 今的SELECT語句跟以前的已經大相徑庭了,因爲現在只要用戶名爲長度爲零的字符串''或1=1這兩個條件中一個爲真,就返回用戶標識符ID——我們知 道,1=1是恆爲真的。所以這個語句將返回user_table中的所有ID。在此種情況下,攻擊者在username字段放入的是SQL指令 'OR1=1--而非數據。
更爲嚴重的情況是當username對應的是'OR1=1;DROPTABLEuser_table;--
數據庫中執行的sql語句就變成了:
select id from test where username='' or 1=1;drop table test
這個語句將執行句法上完全正確的SELECT語句,並利用drop命令清空test表。
應對策略
問題的關鍵就是不要用string構造sql語句,這樣就不會利用輸入的參數構造sql語句了。所以要用PreparedStatement替換Statement,即用佔位符作爲實參定義sql語句,從而避免sql注入攻擊。
不管什麼框架,還是純JDBC,只用Preparedstatement,一定要用佔位符作爲實參來構造sql(或hql)語句。

String sql= "select * from test where usernmae=? and password=? " ;
PreparedStatement psm=conn.preparedStatement(sql);
psm.setString(1,myname);
psm.setString(2,mypasswd);
Result rs=psm.executeQuery();
 
if (rs.next){
rs.close();
con.close();
return false ;
}
else {
rs.close();
con.close();
return true ;
}
發佈了74 篇原創文章 · 獲贊 17 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章