大家都不陌生,是一種常見的攻擊方式。攻擊者在介面的表單資訊或url上輸入一些奇怪的sql片段(例如「or 『1』=』1』」這樣的語句),有可能入侵引數檢驗不足的應用程式。所以,在我們的應用中需要做一些工作,來防備這樣的攻擊方式。
在一些安全性要求很高的應用中(比如銀行軟體),經常使用將sql語句全部替換為儲存過程這樣的方式,來防止sql注入。這當然是一種很安全的方式,但我們平時開發中,可能不需要這種死板的方式。
例:
string sql = "select * from user_table where username=
' "+username+" ' and password=
' "+password+" '";
--當輸入了上面的使用者名稱和密碼,上面的sql語句變成:
select * from user_table where username=
'』or 1 = 1 -- and password='』
--分析sql語句:
--條件後面username=」or 1
=1 使用者名稱等於 」 或1
=1 那麼這個條件一定會成功;
--然後後面加兩個-,這意味著注釋,它將後面的語句注釋,讓他們不起作用,這樣語句永遠都--能正確執行,使用者輕易騙過系統,獲取合法身份。
--這還是比較溫柔的,如果是執行
select * from user_table where
username=
'';drop database (db name)
--' and password=''
--其後果可想而知…
首先#{}和${}在預編譯中的處理是不一樣的。
#在預處理時,會把引數部分用乙個佔位符 ?代替,變成如下的sql語句:
select * from user where name =?;
替換引數 --
> select * from user where name =
'seattle'
$則只是簡單的字串替換,在動態解析階段,該sql語句會被解析成
select * from user where name = seattle;
mybatis框架作為一款半自動化的持久層框架,其sql語句都要我們自己手動編寫,這個時候當然需要防止sql注入。其實,mybatis的sql是乙個具有「輸入+輸出」的功能,類似於函式的結構,參考上面的兩個例子。其中,parametertype表示了輸入的引數型別,resulttype表示了輸出的引數型別。回應上文,如果我們想防止sql注入,理所當然地要在輸入引數上下功夫。上面**中使用#的即輸入引數在sql中拼接的部分,傳入引數後,列印出執行的sql語句,會看到sql是這樣的:
select id, username, password, role from user where username=
? and password=
?
不管輸入什麼引數,列印出的sql都是這樣的。這是因為mybatis啟用了預編譯功能,在sql執行前,會先將上面的sql傳送給資料庫進行編譯;執行時,直接使用編譯好的sql,替換佔位符「?」就可以了。因為sql注入只能對編譯過程起作用,所以這樣的方式就很好地避免了sql注入的問題。
【底層實現原理】mybatis是如何做到sql預編譯的呢?其實在框架底層,是jdbc中的preparedstatement類在起作用,preparedstatement是我們很熟悉的statement的子類,它的物件包含了編譯好的sql語句。這種「準備好」的方式不僅能提高安全性,而且在多次執行同乙個sql時,能夠提高效率。原因是sql已編譯好,再次執行時無需再編譯。
statement語法
statement stmt =
connect
.createstatement();
string sql
="select * from cg_user where userid=10086 and name like 'xiaoming'"
;resultset rs = stmt.executequery(
sql)
;preparedstatement語法
1、 preparedstatement介面繼承statement, preparedstatement 例項包含已編譯的 sql 語句,所以其執行速度要快於 statement 物件。
2、作為 statement 的子類,preparedstatement 繼承了 statement 的所有功能。三種方法 execute、 executequery 和 executeupdate 已被更改以使之不再需要引數
3、使用「?」佔位符提公升**的可讀性和可維護性.
4、使用 preparedstatement 最重要的一點好處是它擁有更佳的效能優勢,sql語句會預編譯在資料庫系統中。執行計畫同樣會被快取起來,它允許資料庫做引數化查詢。
5、preparedstatement可以防止sql注入式攻擊。在使用引數化查詢的情況下,資料庫系統(eg:mysql)不會將引數的內容視為sql指令的一部分來處理,而是在資料庫完成sql指令的編譯後,才套用引數執行,因此就算引數中含有破壞性的指令,也不會被資料庫所執行。
SQL注入(三) sql注入 bugku
原理 mysql 在使用 gbk 編碼的時候,會認為兩個字元為乙個漢字,例如 aa 5c 就是乙個 漢字 前乙個 ascii碼大於 128 才能到漢字的範圍 我們在過濾 的時候,往往利用的思 路是將 轉換為 換的函式或者思路會在每一關遇到的時候介紹 因此我們在此想辦法將 前面新增的 除掉,一般有兩種...
SQL注入 報錯注入
乙個帶get引數的 並且不從資料庫返回資料,但存在報錯資訊 檢視字段情況 報錯注入語句格式 and 1 2 union select1,2,3 from select count concat floor rand 0 2 sql語句 a from information schema.tables...
SQL注入 報錯注入
sql注入基礎 盲注 用於注入結果無回顯但錯誤資訊有輸出的情況 floor函式 返回小於等於某值的整數,例如floor 1 則返回1,floor 1.9 也返回1 rand函式 生成隨機數.可指定seed,指定後每次生成的數都一樣即偽隨機,不指定seed則每次生成的隨機數都不一樣.通過floor和r...