文章目錄
簡介
sql注入
java中的sql注入
使用preparedstatement
xml中的sql注入
xml注入的java代碼
注入問題是安全中一個非常常見的問題,今天我們來探讨一下java中的sql注入和xml注入的防範。
什麼是sql注入呢?
sql注入的意思是,使用者輸入了某些參數,最終導緻sql的執行偏離了程式設計者的本意,進而導緻越權或者其他類型的錯誤。
也就是說因為使用者輸入的原因,導緻sql的涵義發送了變化。
拿我們最常用的登入的sql語句來說,我們可能會寫下面的sql語句:
我們需要使用者傳入username和password。
怎麼對這個sql語句進行注入呢?
很簡單,當使用者的username輸入是下面的情況時:
那麼整個sql語句将會變成:
如果somebody是一個有效的使用者,那麼or後面的語言完全不會執行,最終導緻不校驗密碼就傳回了使用者的資訊。
同樣的,惡意攻擊者可以給password輸入下面的内容可以得到同樣的結果:
整個sql解析為:
這條語句将會傳回所有的使用者資訊,這樣即使不知道确定存在的使用者名也可以通過sql語句的判斷。
這就是sql注入。
java中最常用的就是通過jdbc來操作資料庫,我們使用jdbc建立好連接配接之後,就可以執行sql語句了。
下面我們看一個java中使用jdbc sql注入的例子。
先建立一個通用的jdbc連接配接:
然後再自己拼裝sql語句然後調用:
上面的例子中,隻有username會發生注入,password不會,因為我們使用了encodepassword方法對password進行了轉換:
為了防止sql注入,我們一般推薦的是使用preparedstatement,java.sql.preparedstatement可對輸入參數進行轉義,進而防止sql注入。
注意,一定要正确的使用preparedstatement,如果是不正确的使用,同樣會造成sql注入的結果。
下面看一個不正确使用的例子:
上面的代碼中,我們還是自己進行了sql的拼裝,雖然最後我們使用了preparedstatement,但是沒有達到效果。
正确使用的例子如下:
我們需要将使用者輸入作為參數set到preparedstatement中去,這樣才會進行轉義。
可擴充标記語言(xml)旨在幫助存儲,結構化和傳輸資料。 由于其平台獨立性,靈活性和相對簡單性,xml已在許多應用程式中得到使用。 但是,由于xml的多功能性,它容易受到包括xml注入在内的各種攻擊的攻擊。
那麼什麼是xml注入呢?我們舉個例子:
上面的例子中,我們使用了xml定義了一個iphone20的價格和數量。一個iphone20 5000塊。
上面的xml中,如果quantity是使用者輸入的資料的話,那麼使用者可以這樣輸入:
最後得出的xml檔案如下:
一般來說,我們在解析xml的過程中,如果發現有重複的tag,那麼後面的tag會覆寫前面的tag。
結果就是1個iphone20現在的價格是20塊,非常劃算。
我們看下xml的注入在java代碼中是怎麼實作的:
可以看到我們直接使用使用者輸入的quantity作為xml的拼接,這樣做很明顯是有問題的。
怎麼解決呢?有兩種方法。
第一種方法
第一種方法就是對使用者輸入的quantity進行校驗:
上面代碼中,我們對quantity進行了integer的轉換,進而避免了使用者的非法輸入。
第二種方法
第二種方法是使用xml schema,來對生成的xml進行格式校驗。
先看一下我們改怎麼定義這個xml schema:
上面我們定義了一個xml element的序列sequence。如果使用者輸入了非定義格式的其他xml,就會報錯。
我們看下相對應的java代碼該怎麼寫:
上面我們列出了xml驗證的代碼,完整的代碼可以參考文末的代碼連結,這裡就不一一貼出來了。
本文的代碼:
learn-java-base-9-to-20/tree/master/security