最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis 防止 SQL 注入的正確用法

 更新時間:2026年03月30日 09:19:04   作者:莫寒清  
文章主要講述了MyBatis防止SQL注入的方法,強調(diào)了使用#{param}進行參數(shù)綁定,避免使用${param}拼接SQL,對于必須使用的${}需做白名單或使用<choose>枚舉替代,并提出了編碼規(guī)范、代碼評審、審計與測試等多層防護建議,感興趣的朋友一起看看吧

一句話總結(jié)

MyBatis 防 SQL 注入的核心是:參數(shù)一律使用 #{} 做“參數(shù)綁定”(PreparedStatement 的 ? 占位),讓“SQL 結(jié)構(gòu)”和“數(shù)據(jù)”徹底分離;對不得不用 ${} 的 表名/列名/排序 等 SQL 片段,必須做 白名單 或用 <choose> 枚舉替代;同時配合代碼規(guī)范、審計與測試實現(xiàn)多層防護。

1. 先搞清楚:SQL 注入的本質(zhì)是什么?

SQL 注入并不是“沒轉(zhuǎn)義”,而是:把用戶輸入拼進 SQL 語法結(jié)構(gòu)里,導致輸入從“數(shù)據(jù)”變成“指令”。

因此最可靠的防護手段是:

  • 參數(shù)綁定(PreparedStatement):輸入永遠作為參數(shù)值傳遞,不參與 SQL 語法解析。

2. MyBatis 兩種替換方式:#{}vs${}(核心)

寫法本質(zhì)是否安全適用場景
#{param}生成 ? 占位符 + JDBC 參數(shù)綁定(TypeHandler)安全WHERE/INSERT/UPDATE 的“值”
${param}文本原樣拼接到 SQL(字符串替換)高風險表名/列名/ORDER BY 等“SQL 片段”

結(jié)論:

  • 能用 #{} 就絕不用 ${}
  • ${} 只在“無法用 ? 占位”的場景出現(xiàn),并且必須白名單。

3. 正確用法 1:所有“值”都用#{}(參數(shù)綁定)

3.1 基本示例

<select id="findByName" resultType="User">
  SELECT * FROM user WHERE name = #{name}
</select>

SQL 形態(tài):

SELECT * FROM user WHERE name = ?

此時即使輸入是 admin' OR '1'='1,也只會作為一個字符串值去匹配,不會改變 SQL 結(jié)構(gòu)。

3.2 關(guān)鍵點補充:TypeHandler / JDBC 類型處理

#{} 會走 MyBatis 的 TypeHandler,由它決定用 setString/setInt/... 綁定參數(shù)。

  • 這不是簡單“字符串轉(zhuǎn)義”,而是參數(shù)綁定。
  • 防注入的關(guān)鍵在于“結(jié)構(gòu)與數(shù)據(jù)分離”。

4. 正確用法 2:動態(tài) SQL 標簽是安全的(前提是內(nèi)部仍用#{})

MyBatis 的動態(tài) SQL(<if> / <where> / <trim> / <choose>)只是動態(tài)組裝 SQL 結(jié)構(gòu),并不等于把用戶輸入拼進 SQL。

只要條件值仍用 #{},就是安全的:

<select id="query" resultType="User">
  SELECT * FROM user
  <where>
    <if test="name != null and name != ''">
      AND name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
  </where>
</select>

5. 常見攻擊面與正確寫法

5.1LIKE模糊查詢

推薦(仍用 #{}):

WHERE name LIKE CONCAT('%', #{name}, '%')

不要用:

WHERE name LIKE '%${name}%'

注入后果示例:
若用戶輸入 name' OR '1'='1,生成的 SQL 將變?yōu)椋?br />WHERE name LIKE '%' OR '1'='1'%'
由于 '1'='1' 恒成立,該查詢會繞過名稱過濾,直接返回全表數(shù)據(jù),導致敏感信息泄露。

5.2IN查詢(批量參數(shù))

使用 <foreach> 生成多個 #{}

<select id="selectByIds" resultType="User">
  SELECT * FROM user
  WHERE id IN
  <foreach collection="ids" item="id" open="(" separator="," close=")">
    #{id}
  </foreach>
</select>

不要把整段 ids 字符串塞進 ${}。

風險/后果:
如果把用戶輸入的 ids 直接拼成 IN (${ids}),攻擊者可構(gòu)造如 1) OR 1=1 --,最終 SQL 可能變?yōu)椋?br />WHERE id IN (1) OR 1=1 --)
從而導致 IN 條件被繞過、返回全表數(shù)據(jù),甚至在支持多語句的配置下進一步造成更嚴重的破壞。

5.3 分頁參數(shù)

分頁參數(shù)也屬于“值”,用 #{}

SELECT * FROM user LIMIT #{offset}, #{pageSize}

6. 不得不用${}的場景:必須白名單/枚舉替代

6.1 為什么這些場景不能用#{}?

JDBC 的 ? 占位符只能替換,不能替換:

  • 表名、列名
  • ORDER BY 的字段
  • ASC/DESC 關(guān)鍵字

因此這些場景可能出現(xiàn) ${}。

6.2 推薦做法:用<choose>枚舉排序字段(避免透傳${sortField})

<select id="findUsers" resultType="User">
  SELECT * FROM user
  <choose>
    <when test="sortField == 'age'">ORDER BY age</when>
    <when test="sortField == 'name'">ORDER BY name</when>
    <otherwise>ORDER BY id</otherwise>
  </choose>
  <choose>
    <when test="sortOrder == 'DESC'">DESC</when>
    <otherwise>ASC</otherwise>
  </choose>
</select>

6.3 業(yè)務(wù)側(cè)白名單映射(如果必須用${})

  • 輸入只允許來自固定集合(枚舉/Map 映射),嚴禁直接使用用戶原始字符串。
  • 對排序字段、表名、列名做正向校驗(white list),不要做“黑名單過濾”。

7. 常見誤區(qū)(糾錯點)

  1. 誤區(qū):#{} 是“自動轉(zhuǎn)義”所以安全
    • 更準確:#{}參數(shù)綁定(結(jié)構(gòu)與數(shù)據(jù)分離),不是靠轉(zhuǎn)義。
  2. 誤區(qū):動態(tài) SQL 一定安全
    • 動態(tài)標簽本身安全,但如果你在標簽里用 ${} 拼接用戶輸入,一樣會注入。
  3. 誤區(qū):把 '${name}' 包上引號就安全
    • 仍是拼接,依然可能被構(gòu)造輸入突破。

8. 多層防護(生產(chǎn)建議)

僅靠 ORM 習慣不夠,建議組合:

  • 編碼規(guī)范:禁止 ${} 透傳用戶輸入;代碼評審強制檢查
  • 參數(shù)校驗:對排序字段、表名等做枚舉/白名單校驗
  • 審計與測試:單測/集成測試加入注入 payload(如 "' OR '1'='1"
  • 最小權(quán)限:DB 賬號權(quán)限最小化(禁止高危權(quán)限)
  • 可選:WAF/SQL 防火墻/數(shù)據(jù)庫審計(兜底)

9. 面試速答

  • Q:MyBatis 如何防 SQL 注入?
    • A:對值使用 #{} 走 PreparedStatement 參數(shù)綁定;對必須拼接的 SQL 片段(表名/列名/排序)使用白名單或 <choose> 枚舉,禁止 ${} 透傳用戶輸入。
  • Q:${} 為什么危險?
    • A:它是文本替換,輸入會進入 SQL 結(jié)構(gòu),可能變成指令。
  • Q:IN / LIKE 怎么寫才安全?
  • A:IN<foreach> + #{};LIKECONCAT('%', #{x}, '%')

到此這篇關(guān)于MyBatis 防止 SQL 注入的正確用法的文章就介紹到這了,更多相關(guān)MyBatis 防止 SQL 注入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 開啟多線程常見的4種方法

    Java 開啟多線程常見的4種方法

    本文主要介紹了Java 開啟多線程常見的4種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • SpringBoot集成XXL-JOB實現(xiàn)靈活控制的分片處理方案

    SpringBoot集成XXL-JOB實現(xiàn)靈活控制的分片處理方案

    因為需要并行處理同一張數(shù)據(jù)表里的數(shù)據(jù),所以比較自然地想到了分片查詢數(shù)據(jù),可以利用對 id 取模的方法進行分片,避免同一條數(shù)據(jù)被重復處理,所以本文給大家介紹了SpringBoot集成XXL-JOB實現(xiàn)靈活控制的分片處理方案,需要的朋友可以參考下
    2024-09-09
  • 編寫android撥打電話apk應(yīng)用實例代碼

    編寫android撥打電話apk應(yīng)用實例代碼

    這篇文章主要介紹了編寫android撥打電話apk應(yīng)用實例代碼,十分的實用,這里分享給大家,有需要的小伙伴可以參考下
    2015-04-04
  • IDEA中創(chuàng)建maven項目webapp目錄無法識別即未被標識的解決辦法

    IDEA中創(chuàng)建maven項目webapp目錄無法識別即未被標識的解決辦法

    在學習SpringMVC課程中,基于IDEA新建maven項目模塊后,webapp目錄未被標識,即沒有小藍點的圖標顯示,所以本文給大家介紹了IDEA中創(chuàng)建maven項目webapp目錄無法識別即未被標識的解決辦法,需要的朋友可以參考下
    2024-03-03
  • 使用開源項目JAVAE2 進行視頻格式轉(zhuǎn)換

    使用開源項目JAVAE2 進行視頻格式轉(zhuǎn)換

    這篇文章主要介紹了使用開源項目JAVAE 進行視頻格式轉(zhuǎn)換,幫助大家更好的利用Java處理視頻,完成自身需求,感興趣的朋友可以了解下
    2020-11-11
  • 淺談Java接口響應(yīng)速度優(yōu)化

    淺談Java接口響應(yīng)速度優(yōu)化

    在Java開發(fā)中,接口響應(yīng)速度直接影響用戶體驗和系統(tǒng)吞吐量,優(yōu)化接口性能需要從代碼、數(shù)據(jù)庫、緩存、架構(gòu)等多個維度綜合考量,下面就來具體了解一下
    2025-08-08
  • Java使用字節(jié)流復制文件的方法

    Java使用字節(jié)流復制文件的方法

    這篇文章主要為大家詳細介紹了Java使用字節(jié)流復制文件的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 在Mac系統(tǒng)上安裝Java和IntelliJ?IDEA完整筆記

    在Mac系統(tǒng)上安裝Java和IntelliJ?IDEA完整筆記

    IntelliJ IDEA的智能代碼輔助功能堪稱一絕,它具備強大的代碼自動補全能力,能依據(jù)上下文精準推測開發(fā)者的意圖,提供極為準確的代碼建議,這篇文章主要介紹了在Mac系統(tǒng)上安裝Java和IntelliJ?IDEA的相關(guān)資料,需要的朋友可以參考下
    2026-02-02
  • Jmeter命令行執(zhí)行腳本如何設(shè)置動態(tài)參數(shù)

    Jmeter命令行執(zhí)行腳本如何設(shè)置動態(tài)參數(shù)

    這篇文章主要介紹了Jmeter命令行執(zhí)行腳本如何設(shè)置動態(tài)參數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • Spring?Cache?集成?Caffeine實現(xiàn)項目緩存的示例

    Spring?Cache?集成?Caffeine實現(xiàn)項目緩存的示例

    本文主要介紹了Spring?Cache?集成?Caffeine實現(xiàn)項目緩存的示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12

最新評論

呼伦贝尔市| 伊吾县| 扶绥县| 文山县| 日喀则市| 黔东| 白水县| 万山特区| 岱山县| 南木林县| 云南省| 曲靖市| 古浪县| 乌兰察布市| 千阳县| 青神县| 自治县| 佛冈县| 宝兴县| 华安县| 基隆市| 巴中市| 家居| 芜湖市| 桃园县| 常宁市| 长兴县| 永寿县| 武山县| 蚌埠市| 沈丘县| 安乡县| 额敏县| 武城县| 武威市| 琼中| 镇坪县| 遵义市| 宜都市| 丰都县| 卫辉市|