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