日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

sql注入及mybatis防止sql注入

發(fā)布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sql注入及mybatis防止sql注入 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、Sql 注入漏洞詳解

  • Sql 注入產(chǎn)生原因及威脅:
  • 當(dāng)我們訪問動態(tài)網(wǎng)頁時, Web 服務(wù)器會向數(shù)據(jù)訪問層發(fā)起 Sql 查詢請求,如果權(quán)限驗證通過就會執(zhí)行 Sql 語句。這種網(wǎng)站內(nèi)部直接發(fā)送的Sql請求一般不會有危險,但實際情況是很多時候需要結(jié)合用戶的輸入數(shù)據(jù)動態(tài)構(gòu)造 Sql 語句,如果用戶輸入的數(shù)據(jù)被構(gòu)造成惡意 Sql 代碼,Web 應(yīng)用又未對動態(tài)構(gòu)造的 Sql 語句使用的參數(shù)進(jìn)行審查,則會帶來意想不到的危險。

    Sql 注入帶來的威脅主要有如下幾點

  • 猜解后臺數(shù)據(jù)庫,這是利用最多的方式,盜取網(wǎng)站的敏感信息。
  • 繞過認(rèn)證,列如繞過驗證登錄網(wǎng)站后臺。
  • 注入可以借助數(shù)據(jù)庫的存儲過程進(jìn)行提權(quán)等操作
  • Sql 注入示例一.猜解數(shù)據(jù)庫
  • 接下來我們通過一個實例,讓你更加清楚的理解 Sql 注入猜解數(shù)據(jù)庫是如何發(fā)生的。使用DVWA滲透測試平臺,作為攻擊測試的目標(biāo):

    先輸入 1 ,查看回顯 (URL中ID=1,說明php頁面通過get方法傳遞參數(shù)):

    那實際上后臺執(zhí)行了什么樣的Sql語句呢? ,其中的SQL查詢代碼為:

    可以看到,實際執(zhí)行的Sql語句是:

    SELECT first_name, last_name FROM users WHERE user_id = '1';

    我們是通過控制參數(shù)Id的值來返回我們需要的信息。
    如果我們不按常理出牌,比如在輸入框中輸入 1' order by 1#
    實際執(zhí)行的Sql語句就會變成:

    SELECT first_name, last_name FROM users WHERE user_id = '1' order by 1#`;(按照Mysql語法,#后面會被注釋掉,使用這種方法屏蔽掉后面的單引號,避免語法錯誤)

    這條語句的意思是查詢users表中user_id為1的數(shù)據(jù)并按第一字段排行。

    輸入 1’ order by 1#和 1’ order by 2#時都返回正常:


    當(dāng)輸入 1’ order by 3#時,返回錯誤:

    由此可知,users表中只有兩個字段,數(shù)據(jù)為兩列。

    接下來我們使用 union select聯(lián)合查詢繼續(xù)獲取信息。
    union 運算符可以將兩個或兩個以上 select 語句的查詢結(jié)果集合合并成一個結(jié)果集合顯示,即執(zhí)行聯(lián)合查詢。需要注意在使用 union 查詢的時候需要和主查詢的列數(shù)相同,而我們之前已經(jīng)知道了主查詢列數(shù)為 2,接下來就好辦了。
    輸入1’ union select database(),user()#進(jìn)行查詢 :

    • database()將會返回當(dāng)前網(wǎng)站所使用的數(shù)據(jù)庫名字.
    • user()將會返回執(zhí)行當(dāng)前查詢的用戶名.

    實際執(zhí)行的Sql語句是 :

    SELECT first_name, last_name FROM users WHERE user_id = '1' union select database(),user()#`;

    通過上圖返回信息,我們成功獲取到:

    • 當(dāng)前網(wǎng)站使用數(shù)據(jù)庫為 dvwa .
    • 當(dāng)前執(zhí)行查詢用戶名為 root@localhost .

    同理我們再輸入 1' union select version(),@@version_compile_os#進(jìn)行查詢:

    • version() 獲取當(dāng)前數(shù)據(jù)庫版本.
    • @@version_compile_os 獲取當(dāng)前操作系統(tǒng)。

    實際執(zhí)行的Sql語句是:

    SELECT first_name, last_name FROM users WHERE user_id = '1' union select version(),@@version_compile_os#`;

    通過上圖返回信息,我們又成功獲取到:

    • 當(dāng)前數(shù)據(jù)庫版本為 : 5.6.31-0ubuntu0.15.10.1.
    • 當(dāng)前操作系統(tǒng)為 : debian-linux-gnu

    接下來我們嘗試獲取 dvwa 數(shù)據(jù)庫中的表名。
    information_schema 是 mysql 自帶的一張表,這張數(shù)據(jù)表保存了 Mysql 服務(wù)器所有數(shù)據(jù)庫的信息,如數(shù)據(jù)庫名,數(shù)據(jù)庫的表,表欄的數(shù)據(jù)類型與訪問權(quán)限等。該數(shù)據(jù)庫擁有一個名為 tables 的數(shù)據(jù)表,該表包含兩個字段 table_name 和 table_schema,分別記錄 DBMS 中的存儲的表名和表名所在的數(shù)據(jù)庫。

    我們輸入1’ union select table_name,table_schema from information_schema.tables where table_schema= ‘dvwa’#進(jìn)行查詢:
    實際執(zhí)行的Sql語句是:

    SELECT first_name, last_name FROM users WHERE user_id = '1' union select table_name,table_schema from information_schema.tables where table_schema= 'dvwa'#`;

    通過上圖返回信息,我們再獲取到:

    • dvwa 數(shù)據(jù)庫有兩個數(shù)據(jù)表,分別是 guestbook 和 users .

    有些同學(xué)肯定還不滿足目前獲取到的信息,那么我們接下來嘗試獲取重量級的用戶名、密碼。由經(jīng)驗我們可以大膽猜測users表的字段為 user 和 password ,所以輸入:1' union select user,password from users#進(jìn)行查詢:
    實際執(zhí)行的 Sql 語句是:

    SELECT first_name, last_name FROM users WHERE user_id = '1' union select user,password from users#`;

    可以看到成功爆出用戶名、密碼,密碼采用 md5 進(jìn)行加密,可以到www.cmd5.com進(jìn)行解密。直此,同學(xué)們應(yīng)該已經(jīng)對 Sql 注入有了一個大概得了解,也清楚了 Sql 注入的強大。

  • Sql 注入實例二.驗證繞過
  • 接下來我們再試試另一個利用 Sql 漏洞繞過登錄驗證的實例。
    使用事先編寫好的頁面,這是一個普通的登錄頁面,只要輸入正確的用戶名和密碼就能登錄成功。

    我們先嘗試隨意輸入用戶名 123 和密碼 123 登錄:

    從錯誤頁面中我們無法獲取到任何信息。
    看看后臺代碼如何做驗證的:

    實際執(zhí)行的操作時:

    select * from users where username='123' and password='123'

    當(dāng)查詢到數(shù)據(jù)表中存在同時滿足 username 和 password 字段時,會返回登錄成功。按照第一個實例的思路,我們嘗試在用戶名中輸入 123' or 1=1 #, 密碼同樣輸入 123' or 1=1 # :


    為什么能夠成功登陸呢?因為實際執(zhí)行的語句是:

    select * from users where username='123' or 1=1 #' and password='123' or 1=1 #'

    按照 Mysql 語法,# 后面的內(nèi)容會被忽略,所以以上語句等同于(實際上密碼框里不輸入任何東西也一樣):

    select * from users where username='123' or 1=1

    由于判斷語句 or 1=1 恒成立,所以結(jié)果當(dāng)然返回真,成功登錄。
    我們再嘗試不使用 # 屏蔽單引號,采用手動閉合的方式:
    我們嘗試在用戶名中輸入 123’ or ‘1’=‘1, 密碼同樣輸入 123’ or ‘1’='1 (不能少了單引號,否則會有語法錯誤):


    實際執(zhí)行的 Sql 語句是:

    select * from users where username='123' or '1'='1' and password='123' or '1'='1

    看到了嗎?兩個 or 語句使 and 前后兩個判斷永遠(yuǎn)恒等于真,所以能夠成功登錄。還有很多其他 Mysql 語句可以巧妙的繞過驗證,同學(xué)們可以發(fā)散自己的思維進(jìn)行嘗試。

    二、判斷 Sql 注入點

    通常情況下,可能存在 Sql 注入漏洞的 Url 是類似這種形式 :http://xxx.xxx.xxx/abcd.php?id=XX
    對 Sql 注入的判斷,主要有兩個方面:

    • 判斷該帶參數(shù)的 Url 是否存在 Sql 注入?
    • 如果存在 Sql 注入,那么屬于哪種 Sql 注入?

    可能存在 Sql 注入攻擊的 ASP/PHP/JSP 動態(tài)網(wǎng)頁中,一個動態(tài)網(wǎng)頁中可能只有一個參數(shù),有時可能有多個參數(shù)。有時是整型參數(shù),有時是字符串型參數(shù),不能一概而論。總之只要是帶有參數(shù)的動態(tài)網(wǎng)頁且此網(wǎng)頁訪問了數(shù)據(jù)庫,那么就有可能存在 Sql 注入。如果程序員沒有足夠的安全意識,沒有進(jìn)行必要的字符過濾,存在SQL注入的可能性就非常大。

  • 判斷是否存在 Sql 注入漏洞
  • 最為經(jīng)典的單引號判斷法:
    在參數(shù)后面加上單引號,比如:

    http://xxx/abc.php?id=1'

    如果頁面返回錯誤,則存在 Sql 注入。原因是無論字符型還是整型都會因為單引號個數(shù)不匹配而報錯。(如果未報錯,不代表不存在 Sql 注入,因為有可能頁面對單引號做了過濾,這時可以使用判斷語句進(jìn)行注入,因為此為入門基礎(chǔ)課程,就不做深入講解了)

  • 判斷 Sql 注入漏洞的類型
  • 通常 Sql 注入漏洞分為 2 種類型:

    • 數(shù)字型
    • 字符型

    其實所有的類型都是根據(jù)數(shù)據(jù)庫本身表的類型所產(chǎn)生的,在我們創(chuàng)建表的時候會發(fā)現(xiàn)其后總有個數(shù)據(jù)類型的限制,而不同的數(shù)據(jù)庫又有不同的數(shù)據(jù)類型,但是無論怎么分常用的查詢數(shù)據(jù)類型總是以數(shù)字與字符來區(qū)分的,所以就會產(chǎn)生注入點為何種類型。

    • 數(shù)字型判斷:
      當(dāng)輸入的參 x 為整型時,通常 abc.php 中 Sql 語句類型大致如下:
    select * from <表名> where id = x

    這種類型可以使用經(jīng)典的 and 1=1 和 and 1=2 來判斷:

    • Url 地址中輸入 http://xxx/abc.php?id= x and 1=1 頁面依舊運行正常,繼續(xù)進(jìn)行下一步。
    • Url地址中繼續(xù)輸入 http://xxx/abc.php?id= x and 1=2 頁面運行錯誤,則說明此 Sql 注入為數(shù)字型注入。

    原因如下:
    當(dāng)輸入 and 1=1時,后臺執(zhí)行 Sql 語句:

    select * from <表名> where id = x and 1=1

    沒有語法錯誤且邏輯判斷為正確,所以返回正常。

    當(dāng)輸入 and 1=2時,后臺執(zhí)行 Sql 語句:

    select * from <表名> where id = x and 1=2

    沒有語法錯誤但是邏輯判斷為假,所以返回錯誤。
    我們再使用假設(shè)法:如果這是字符型注入的話,我們輸入以上語句之后應(yīng)該出現(xiàn)如下情況:

    select * from <表名> where id = 'x and 1=1' select * from <表名> where id = 'x and 1=2'

    查詢語句將 and 語句全部轉(zhuǎn)換為了字符串,并沒有進(jìn)行 and 的邏輯判斷,所以不會出現(xiàn)以上結(jié)果,故假設(shè)是不成立的。

    • 字符型判斷:
      當(dāng)輸入的參 x 為字符型時,通常 abc.php 中 SQL 語句類型大致如下:
    select * from <表名> where id = 'x'

    這種類型我們同樣可以使用 and '1'='1 和 and '1'='2來判斷:

    • Url 地址中輸入 http://xxx/abc.php?id= x' and '1'='1 頁面運行正常,繼續(xù)進(jìn)行下一步。
    • Url地址中繼續(xù)輸入 http://xxx/abc.php?id= x' and '1'='2 頁面運行錯誤,則說明此 Sql 注入為字符型注入。

    原因如下:
    當(dāng)輸入 and '1'='1時,后臺執(zhí)行 Sql 語句:

    select * from <表名> where id = 'x' and '1'='1'

    語法正確,邏輯判斷正確,所以返回正確。

    當(dāng)輸入 and '1'='2時,后臺執(zhí)行 Sql 語句:

    select * from <表名> where id = 'x' and '1'='2'

    語法正確,但邏輯判斷錯誤,所以返回正確。同學(xué)們同樣可以使用假設(shè)法來驗證。

    三、Mybatis防止sql注入

    下面是MyBatis一個Dao配置

    <select id="findRank" parameterType ="String" resultType="String">SELECT u.name FROM UserInfo uwhere 1=1 and u.UserID=#{userID} ; </select>

    打印出執(zhí)行的SQL語句

    SELECT u.name FROM UserInfo u where 1=1 and u.UserID=?

    這是因為MyBatis啟用了預(yù)編譯功能,在SQL執(zhí)行前,會先將上面的SQL發(fā)送給數(shù)據(jù)庫進(jìn)行編譯;執(zhí)行時,直接使用編譯好的SQL,替換占位符“?”就可以了。因為SQL注入只能對編譯過程起作用,所以這樣的方式就很好地避免了SQL注入的問題。

    • 底層實現(xiàn)原理

    MyBatis是如何做到SQL預(yù)編譯的呢?其實在框架底層,是JDBC中的PreparedStatement類在起作用,PreparedStatement是我們很熟悉的Statement的子類,它的對象包含了編譯好的SQL語句。這種“準(zhǔn)備好”的方式不僅能提高安全性,而且在多次執(zhí)行同一個SQL時,能夠提高效率。原因是SQL已編譯好,再次執(zhí)行時無需再編譯。

    話說回來,是否我們使用MyBatis就一定可以防止SQL注入呢?當(dāng)然不是,請看下面的代碼:

    <select id="findRank" parameterType ="String" resultType="String">SELECT u.name FROM UserInfo uwhere 1=1and u.UserID=${userID} ; </select>

    假設(shè)userID=1,將SQL打印出來是這樣的:

    SELECT u.name FROM UserInfo u where 1=1 and u.UserID=1

    假如:

    userID=1;drop table UserInfo ;

    那么sql是這樣的

    SELECT u.name FROM UserInfo u where 1=1 and u.UserID=1;drop table UserInfo ;測試結(jié)果SELECT u.name FROM UserInfo u where 1=1 and u.UserID=1;drop table UserInfo; ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'drop table UserInfo' at line 3 直接報異常,你應(yīng)該慶幸mybaties做了處理,但是不管怎么說${xxx}是無法阻止SQL注入的。
    • “${xxx}”
  • 缺點: 直接參與SQL編譯,不能避免注入攻擊。
  • 優(yōu)點:及到動態(tài)表名和列名時,只能使用“${xxx}”這樣的參數(shù)格式
  • 注意:這樣的參數(shù)需要我們在代碼中手工進(jìn)行處理來防止注入。
  • ${}將傳入的參數(shù)直接顯示生成在sql中,不會添加引號
    • “#{xxx}“
  • 相當(dāng)于JDBC中的PreparedStatement
  • #{}將傳入的參數(shù)當(dāng)成一個字符串,會給傳入的參數(shù)加一個雙引號
  • 優(yōu)點:#{}是經(jīng)過預(yù)編譯的,是安全的;
  • PreparedStatement只能用來為參數(shù)(如參數(shù)值)設(shè)置動態(tài)參數(shù),即用?占位,不可用于表名、字段名等

    參考文章

    與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

    總結(jié)

    以上是生活随笔為你收集整理的sql注入及mybatis防止sql注入的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 久久人人人 | 欧美日韩一区二区三区在线视频 | 免费日韩毛片 | 美女作爱网站 | 国产99视频在线观看 | 男女啪啪无遮挡 | 天堂在线资源库 | 美国色视频 | 三级免费黄录像 | 日韩激情网址 | 欧美精品一二三四区 | 国产精品美女一区 | 日韩精选在线观看 | 最新国产精品视频 | 欧美激情一区二区在线 | 九九热视频这里只有精品 | 亚洲综合精品国产一区二区三区 | av黄色免费在线观看 | 在线资源站 | 久久女女 | www.自拍| 在线观看免费黄网站 | 在线黄网站 | 特大黑人巨交吊性xxxxhd | 免费无遮挡在线观看视频网站 | 欧美一级片一区 | 国产精品久久久久久久久久免费 | 91网站在线免费观看 | 亚洲av综合av一区二区三区 | 97精品国产97久久久久久粉红 | 国产成人一区二区三区别 | 91www在线观看 | www.日本黄| 18久久 | 午夜视频在线免费看 | 久久无码国产视频 | 日日骚av一区二区 | 亚洲v国产v欧美v久久久久久 | 福利所第一导航 | 五月婷婷激情四射 | 中文字幕无码日韩专区免费 | 久久免费视频网 | aa一级片 | 国产一区视频在线 | 97超碰人人模人人人爽人人爱 | 蜜桃视频免费网站 | 毛片视频免费播放 | 在线观看成年人视频 | 在线播放黄色av | 深爱激情五月婷婷 | juliaann第一次和老师 | 午夜视频免费看 | 精品国产99久久久久久宅男i | 国产精品无码AV | 日韩在线视频在线 | 色丁香六月 | 超碰在线cao | 久久久夜色精品 | 亚洲综合一区二区三区 | 欧美v在线 | 在线播放一区 | 后进极品白嫩翘臀在线视频 | 夜色一区| 久久久精品亚洲 | 精品视频一区在线观看 | 色婷婷yy| 亚洲精品乱码久久久久99 | 国产成人精品一区二区三区福利 | 饥渴少妇色诱水电工 | 日韩六九视频 | 日少妇的逼 | 日韩免费淫片 | 综合色婷婷| 91在线视频播放 | 99色在线视频 | 国产精品美女久久久免费 | 四虎在线免费观看视频 | 日本中文字幕不卡 | 麻豆传媒网址 | 欧美精品一线 | 天堂精品一区 | 色天天av | 色夜av | 国偷自产av一区二区三区麻豆 | 精品三级在线观看 | 午夜看片在线 | 欧美污视频 | 一本大道久久精品 | 亚洲国产精品国自产拍av | 亚洲另类色综合网站 | 午夜一区二区三区在线观看 | 亚洲一区二区福利视频 | 激情婷婷综合网 | av加勒比| 欧美日韩三级在线 | 亚洲一区二区三区加勒比 | 国产乱码精品一区二区三区中文 | 亚洲一区动漫 | 麻豆精品久久久久久久99蜜桃 |