摘要本文通過一段JAVA代碼引入SQL注入問題,對SQL注入概念和問題作了詳細介紹,并給出了解決該問題的方法,最后對如何避免SQL注入問題作了總結(jié)。
關鍵詞MYSQLSQL注入方法
中圖分類號:TP31文獻標識碼:A
1 引言
Statement用于執(zhí)行靜態(tài) SQL 語句并返回它所生成結(jié)果的對象。用Statement來處理SQL語句時,可能會產(chǎn)生SQL注入問題,請看如下代碼:
當我們調(diào)用read1(name),且name為數(shù)據(jù)庫中存在的用戶名,就能打印出正確的用戶信息,反之則顯示該用戶不存在的信息。但是當我們嘗試調(diào)用read1('\" or 1 or \"')時,就會把數(shù)據(jù)庫中所有用戶顯示都打印出來,顯然這不是我們希望看到的。為什么會出現(xiàn)這種情況呢?我們來分析一下SQL語句:select id, name, money, birthdayfrom user where name=\" or 1 or \";其中的where name=\" or 1 or \"表示只要name不為0就滿足條件,所有條件都符合記錄,相當于沒有任何限制了,這種方式實際上是很不安全的,以上情況就屬于SQL注入問題之一。
2 相關概念
所謂SQL注入,就是通過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執(zhí)行惡意的SQL命令,比如先前的很多影視網(wǎng)站泄露VIP會員密碼大多就是通過WEB表單遞交查詢字符暴出的,這類表單特別容易受到SQL注入式攻擊.
當應用程序使用輸入內(nèi)容來構造動態(tài)sql語句以訪問數(shù)據(jù)庫時,會發(fā)生sql注入攻擊。如果代碼使用存儲過程,而這些存儲過程作為包含未篩選的用戶輸入的字符串來傳遞,也會發(fā)生sql注入。sql注入可能導致攻擊者使用應用程序登陸在數(shù)據(jù)庫中執(zhí)行命令。如果應用程序使用特權過高的帳戶連接到數(shù)據(jù)庫,這種問題會變得很嚴重。在某些表單中,用戶輸入的內(nèi)容直接用來構造(或者影響)動態(tài)sql命令,或者作為存儲過程的輸入?yún)?shù),這些表單特別容易受到sql注入的攻擊。而許多網(wǎng)站程序在編寫時,沒有對用戶輸入的合法性進行判斷或者程序中本身的變量處理不當,使應用程序存在安全隱患。這樣,用戶就可以提交一段數(shù)據(jù)庫查詢的代碼,根據(jù)程序返回的結(jié)果,獲得一些敏感的信息或者控制整個服務器,于是sql注入就發(fā)生了。
3 解決方法
用繼承于Statement的PreparedStatement可解決SQL注入的問題,SQL 語句被預編譯并存儲在 PreparedStatement 對象中,然后可以使用此對象多次高效地執(zhí)行該語句。下面為改進后的代碼:
由于PreparedStatement處理SQL語句時,它首先對語句中的一些特殊字符進行預處理或者過濾,包括對一些性能進行了優(yōu)化,所以PreparedStatement能解決SQL注入問題。
PreperedStatement(從Statement繼承擴展而來)相對Statement的優(yōu)點:
①不存在SQL注入的問題。
②Statement會使數(shù)據(jù)庫頻繁編譯SQL,可能造成數(shù)據(jù)庫緩沖區(qū)溢出。
③數(shù)據(jù)庫和驅(qū)動可以對PreperedStatement進行優(yōu)化(只有在相關聯(lián)的數(shù)據(jù)庫連接沒有關閉的情況下有效)。
4結(jié)論
一般情況下,對于沒有條件或者條件固定的SQL語句,可以用Statement來處理。但絕大多數(shù)情況下,只要帶有參數(shù)的特別是String類型參數(shù)的SQL語句,在處理時一定要用PreparedStatement來處理,這樣就可以解決SQL注入問題。