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

MyBatis 防止 SQL 注入的正確用法

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

一句話(huà)總結(jié)

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

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

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

因此最可靠的防護(hù)手段是:

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

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

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

結(jié)論:

  • 能用 #{} 就絕不用 ${}。
  • ${} 只在“無(wú)法用 ? 占位”的場(chǎng)景出現(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 = ?

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

3.2 關(guān)鍵點(diǎn)補(bǔ)充:TypeHandler / JDBC 類(lèi)型處理

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

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

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

MyBatis 的動(dòng)態(tài) SQL(<if> / <where> / <trim> / <choose>)只是動(dòng)態(tài)組裝 SQL 結(jié)構(gòu),并不等于把用戶(hù)輸入拼進(jìn) 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. 常見(jiàn)攻擊面與正確寫(xiě)法

5.1LIKE模糊查詢(xún)

推薦(仍用 #{}):

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

不要用:

WHERE name LIKE '%${name}%'

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

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

使用 <foreach> 生成多個(gè) #{}

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

不要把整段 ids 字符串塞進(jìn) ${}。

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

5.3 分頁(yè)參數(shù)

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

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

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

6.1 為什么這些場(chǎng)景不能用#{}?

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

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

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

6.2 推薦做法:用<choose>枚舉排序字段(避免透?jìng)?{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è)白名單映射(如果必須用${})

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

7. 常見(jiàn)誤區(qū)(糾錯(cuò)點(diǎn))

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

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

僅靠 ORM 習(xí)慣不夠,建議組合:

  • 編碼規(guī)范:禁止 ${} 透?jìng)饔脩?hù)輸入;代碼評(píng)審強(qiáng)制檢查
  • 參數(shù)校驗(yàn):對(duì)排序字段、表名等做枚舉/白名單校驗(yàn)
  • 審計(jì)與測(cè)試:?jiǎn)螠y(cè)/集成測(cè)試加入注入 payload(如 "' OR '1'='1"
  • 最小權(quán)限:DB 賬號(hào)權(quán)限最小化(禁止高危權(quán)限)
  • 可選:WAF/SQL 防火墻/數(shù)據(jù)庫(kù)審計(jì)(兜底)

9. 面試速答

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

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

相關(guān)文章

  • Java 開(kāi)啟多線(xiàn)程常見(jiàn)的4種方法

    Java 開(kāi)啟多線(xiàn)程常見(jiàn)的4種方法

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

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

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

    編寫(xiě)android撥打電話(huà)apk應(yīng)用實(shí)例代碼

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

    IDEA中創(chuàng)建maven項(xiàng)目webapp目錄無(wú)法識(shí)別即未被標(biāo)識(shí)的解決辦法

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

    使用開(kāi)源項(xiàng)目JAVAE2 進(jìn)行視頻格式轉(zhuǎn)換

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

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

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

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

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

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

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

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

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

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

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

最新評(píng)論

乌兰浩特市| 惠州市| 淮滨县| 六枝特区| 辽源市| 尖扎县| 博乐市| 满洲里市| 包头市| 社会| 平远县| 湖口县| 嘉善县| 长岛县| 南郑县| 资阳市| 永城市| 佛教| 荥阳市| 镇巴县| 岱山县| 白朗县| 阳谷县| 贺州市| 石柱| 怀远县| 光山县| 邵阳县| 青神县| 恩施市| 兴城市| 吉林省| 化德县| 临西县| 搜索| 青海省| 宿迁市| 石狮市| 姜堰市| 涞水县| 舞阳县|