SQL注入

2022-04-12 04:47:07 字數 2886 閱讀 7972

1:  什麼是sql注入?

string sql = "select * from user_table where username='"+username+" ' and password=' "+password+" '";
username和password是前台傳進來的,如果這裡
username = 'or 1 = 1 #
password = 

那麼sql語句就是: select * from user_table where username=''or 1 = 1 # and password='』

上面的#後面的就被注釋掉了(mysql中的#是注釋符號; sql server裡是--)

(補充:sql 的轉義字元是:'(單引號) 例:select * from tbl where uyear='''06'

請注意其中紅色背景的單引號,它即表示轉義字元,如果我們省略,則整個語句會出錯,轉義字元不會輸出,上例中 uyear 的實際條件值為 '06,而不是 ''06

為什麼不能省略呢,假如我們省略,上句變成:select * from tbl where uyear=''06'由於在 sql 中單引號表示字串的開始和結束符號,於是 sql 直譯器會認為語句中灰色背景的為字串,其後的語句顯然是個錯誤的語句,當然會報錯,為了解決字串的單引號問題,就出現了轉義字元單

2:  spring data jpa, spring jdbc, spring dao 如何防止sql注入?

各種orm都支援引數化查詢,一般的查詢都用引數化的方法就可以防止注入。

(1) 引數化查詢,而不是直接的拼接的sql 文字查詢(plain sql)。資料庫系統都提供sql語句的預編譯(prepare)和查詢引數繫結功能,在sql語句中放置佔位符'?',然後將帶有佔位符的sql語句傳給資料庫編譯,執行的時候才將使用者輸入的資料作為執行的引數傳給使用者。這樣的操作不僅使得sql語句在書寫的時候不再需要拼接,看起來也更直接,而且使用者輸入的資料也沒有機會被送到資料庫的sql直譯器被編譯執行,也不會越權變成**。

繫結變數使用預編譯語句是預防sql注入的最佳方式.

(2) 用正則過濾

(3)字串過濾,有一些特殊情況,不能用引數化查詢的方式,需要過濾。

比如spring工具包的stringescapeutils.escapesql()方法對引數進行過濾. 主要是過濾單引號和注釋。

3: mybatis是如何防止sql注入?

(1). 使用#{}格式的語法在mybatis中使用preparement語句來安全的設定值,執行sql類似下面的:

preparedstatement ps = conn.preparestatement(sql);

ps.setint(1,id);

這樣做的好處是:更安全,更迅速,通常也是首選做法。

(2). 不過有時你只是想直接在 sql 語句中插入乙個不改變的字串。比如,像 order by,你可以這樣來使用:

order by $

此時mybatis 不會修改或轉義字串。

這種方式類似於:

statement st = conn.createstatement();

resultset rs = st.executequery(sql);

這種方式的缺點是: 以這種方式接受從使用者輸出的內容並提供給語句中不變的字串是不安全的,會導致潛在的 sql 注入攻擊,因此要麼不允許使用者輸入這些字段,要麼自行轉義並檢驗。

【結論】在編寫mybatis的對映語句時,盡量採用「#」這樣的格式。若不得不使用「$」這樣的引數,要手工地做好過濾工作,來防止sql注入攻擊。

#{}:相當於jdbc中的preparedstatement

${}:是輸出變數的值

簡單說,#{}是經過預編譯的,是安全的${}是未經過預編譯的,僅僅是取變數的值,是非安全的,存在sql注入。

下邊的例子是用$而不用#的例子:

order by columnname # 

columnnamesort即前端傳的排序方式,asc或者desc。

然後,預計它的輸出應該是類似於下面這樣的

order by columnname desc

但是,真正跑起來時,排序的效果一直沒出現,經常一番查詢,發現是mybatis 的』#{}』傳值的問題,它將sql語句編譯成了如下

order by columnname 'desc' 或者 order by columnname 'asc'

這樣,desc或者asc就成了字串而不是關鍵字,sql語句的意思是columnname的別名是desc或者asc,沒加排序關鍵字時預設是正序排序,成了如下

order by columnname "desc" asc 或者 order by columnname "asc" asc

排序沒效果的問題找到原因了,解決之,mybatis提供了另一種繫結引數的方式–$,將sql配置改為

order by columnname $

這樣一來,mybatis會直接將columnnamesort的值加入sql中,不會轉義。正確結果:

order by columnname desc

最後,對於mybatis中#和$繫結引數的區別做個總結,避免以後類似的問題發生。

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...