preparedstatement本質原理

2021-10-02 09:10:40 字數 1309 閱讀 5476

前幾天拜讀綠盟大佬寫的web應用安全編碼時,看到有一頁ppt上加了一句話備註,preparedstatement預編譯本質也是過濾。就這一點問題我請教了乙個老司機和閱讀了相關資料後,覺得有必要寫出來一下。

string sql="insert into account values(account_seq.nextval,?,?,?)";

pstm = conn.preparestatement(sql, new string );

pstm.setstring(1, a.getname());

pstm.setstring(2,a.getpassword());

pstm.setdouble(3,a.getbalance());

和現在常用開發框架ssm裡的mybatis中的#預編譯一樣,對應statement就是mybatis裡的$:

select id,username,password,age,*** from t_user_info where id=#
其實簡單想一下,這個理論就是經不起推敲的,使用引數化查詢的情況下,資料庫不會將引數的內容視為sql執行的一部分,而是作為乙個欄位的屬性值來處理。問題是如何將其作為乙個欄位的屬性值?如果僅僅是加兩個單引號包起來,那同樣可以用單引號進行惡意sql語句的溢位,因為語句的改變還是會導致重新編譯,即使你預編譯了一些固定語句。

比如上面的preparedstatmen場景顯示應該還是有注入才對

string sql=「insert into account values(account_seq.nextval,?,?,?)」;

pstm = conn.preparestatement(sql, new string );

pstm.setstring(1, 「a』 or 『1』='1」);

查閱了相當多的資料之後,一篇真正的大佬文中做了解釋,每個資料庫處理預編譯的形式不同,而mysql的jar原始碼包中提供了preparedstatement的實現

值得注意的是,此大佬對setstring方法的轉義機制描述有些錯誤,正確的描述應該是在mysql中,是兩邊加單引號,引數中的單引號進行轉義。而setint方法就是對字元型引數進行強制的型別轉換來解決sql注入問題。

答案是肯定的,看了上面推薦blog的setstring方法就知道,並未對%進行轉義,至於為什麼不去轉義%,我是不知道,有興趣的同學可以了解下。。。。。。

如果缺少了%號的轉義,那就必須要考慮模糊查詢like的問題,對於模糊查詢的地方,比如某處固定username後的檢索,都可以進行前置%的形式去繞過預編譯。

owasp提供的esapi中已經增加了對%的處理。

PreparedStatement 事物批量更新

更新資料庫已有的customer資訊 param list return public int updateexistsinfo listupdatelist int tt pstmt.executebatch system.out.println update tt.length 提交,設定事務初...

批處理 PreparedStatement 速度

使用批處理功能涉及到兩個方法 addbatch string 方法 executebatch方法 addbatch方法可以接受一段標準的sql 如果你使用乙個statement 作為引數,也可以什麼引數都不帶 如果你使用乙個preparedstatement executebatch方法接著執行sq...

關於PreparedStatement你知道多少

對應preparedstatement相信大家都很熟悉,那麼為什麼要用preparedstatement呢?也許你會回答preparedstatement為預處理語句,可以提高資料庫執行效率。也許還會回答用preparedstatement可以防止sql注入。那麼再問下,你覺得你對prepareds...