java之SQL注入


前言

在java中,最常見的連接數據庫方式有JDBC,Mybatis,和Hibernate。那我們只需要注意這些地方就可以判斷是否存在sql注入即可

0x01、Mybatis下SQL注入

Mybatis的SQL語句可以基於注解的方式寫在類方法上面,更多的是以xml的方式寫到xml文件。Mybatis中SQL語句需要我們自己手動編寫或者用generator自動生成。

編寫xml文件時,Mybatis支持兩種參數符號,一種是#,另一種是$。比如:

<select id="queryAll"  resultMap="resultMap">
  SELECT * FROM NEWS WHERE ID = #{id}
</select>

而java開發的站點中大部分是預編譯,也就是說存在的sql注入少了;但是,還是有些語句不能進行預編譯,從而導致sql注入。為什么呢?因為預編譯中獲取參數從而執行sql語句使用的#號,然而$符是拼接的意思,像like,in這種使用不規范#符就會報錯,所以就會使用$。那么這種就一定的幾率存在注入,一切看開發是新手還是老司機

導入依賴

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>

<!--mybatis的依賴-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.3</version>
</dependency>

1、like模糊查詢注入

Select * from news where title like '%#{title}%'  //報錯
Select * from news where title like '%${title}%'  //正常

在這種情況下使用#程序會報錯,新手程序員就把#號改成了$,這樣如果java代碼層面沒有對用戶輸入的內容做處理勢必會產生SQL注入漏洞。

正確寫法:

select * from news where tile like concat(‘%’,#{title}, ‘%’)

2、in 注入

in之后多個id查詢時使用# 同樣會報錯,

Select * from news where id in (#{id})  //報錯
Select * from news where id in (${id})  //正常

正確用法為使用foreach,而不是將#替換為$

id in
<foreach collection="id" item="item" open="("separatosr="," close=")">
#{id} 
</foreach>

3、order by 注入

這種場景應當在Java層面做映射,設置一個字段/表名數組,僅允許用戶傳入索引值。這樣保證傳入的字段或者表名都在白名單里面。需要注意的是在mybatis-generator自動生成的SQL語句中,order by使用的也是$,而like和in沒有問題。

Select * from news where title ='#{titlename}' order by #{time} asc //報錯
Select * from news where title ='#{titlename}' order by ${time} asc //正常

總結

總的來說,其實是新手程序員,因為使用#會報錯,從而發現$符不會報錯,進行使用$符;但是本身程序員自己不會用而導致的

java sql注入問題適合使用反推,先搜索xml查找可能存在注入的漏洞點→反推到DAO→再到實現類→再通過調用鏈找到前台URL,找到利用點


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM