国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - 數據庫技術 - SQL注入詳解及防范方法

SQL注入詳解及防范方法

2022-02-12 20:09myseries 數據庫技術

本文詳細講解了SQL注入及防范方法,文中通過示例代碼介紹的非常詳細。對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一:什么是sql注入

SQL注入是比較常見的網絡攻擊方式之一,它不是利用操作系統(tǒng)的BUG來實現攻擊,而是針對程序員編寫時的疏忽,通過SQL語句,實現無賬號登錄,甚至篡改數據庫。

二:SQL注入攻擊的總體思路 

  • 1:尋找到SQL注入的位置
  • 2:判斷服務器類型和后臺數據庫類型
  • 3:針對不同的服務器和數據庫特點進行SQL注入攻擊

三:SQL注入攻擊實例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
String sql = "select * from user_table where username=
' "+userName+" ' and password=' "+password+" '";
 
--當輸入了上面的用戶名和密碼,上面的SQL語句變成:
SELECT * FROM user_table WHERE username=
''or 1 = 1 -- and password=''
 
"""
--分析SQL語句:
--條件后面username=”or 1=1 用戶名等于 ” 或1=1 那么這個條件一定會成功;
 
--然后后面加兩個-,這意味著注釋,它將后面的語句注釋,讓他們不起作用,這樣語句永遠都--能正確執(zhí)行,用戶輕易騙過系統(tǒng),獲取合法身份。
--這還是比較溫柔的,如果是執(zhí)行
SELECT * FROM user_table WHERE
username='' ;DROP DATABASE (DB Name) --' and password=''
--其后果可想而知…
"""

四:如何防御SQL注入

注意:但凡有SQL注入漏洞的程序,都是因為程序要接受來自客戶端用戶輸入的變量或URL傳遞的參數,并且這個變量或參數是組成SQL語句的一部分,對于用戶輸入的內容或傳遞的參數,我們應該要時刻保持警惕,這是安全領域里的「外部數據不可信任」的原則,縱觀Web安全領域的各種攻擊方式,大多數都是因為開發(fā)者違反了這個原則而導致的,所以自然能想到的,就是從變量的檢測、過濾、驗證下手,確保變量是開發(fā)者所預想的。

1、檢查變量數據類型和格式

如果你的SQL語句是類似where id={$id}這種形式,數據庫里所有的id都是數字,那么就應該在SQL被執(zhí)行前,檢查確保變量id是int類型;如果是接受郵箱,那就應該檢查并嚴格確保變量一定是郵箱的格式,其他的類型比如日期、時間等也是一個道理。總結起來:只要是有固定格式的變量,在SQL語句執(zhí)行前,應該嚴格按照固定格式去檢查,確保變量是我們預想的格式,這樣很大程度上可以避免SQL注入攻擊。

比如,我們前面接受username參數例子中,我們的產品設計應該是在用戶注冊的一開始,就有一個用戶名的規(guī)則,比如5-20個字符,只能由大小寫字母、數字以及一些安全的符號組成,不包含特殊字符。此時我們應該有一個check_username的函數來進行統(tǒng)一的檢查。不過,仍然有很多例外情況并不能應用到這一準則,比如文章發(fā)布系統(tǒng),評論系統(tǒng)等必須要允許用戶提交任意字符串的場景,這就需要采用過濾等其他方案了。

2、過濾特殊符號

對于無法確定固定格式的變量,一定要進行特殊符號過濾或轉義處理。

3、綁定變量,使用預編譯語句  

MySQL的mysqli驅動提供了預編譯語句的支持,不同的程序語言,都分別有使用預編譯語句的方法

實際上,綁定變量使用預編譯語句是預防SQL注入的最佳方式,使用預編譯的SQL語句語義不會發(fā)生改變,在SQL語句中,變量用問號?表示,黑客即使本事再大,也無法改變SQL語句的結構

五:什么是sql預編譯

1.1:預編譯語句是什么

通常我們的一條sql在db接收到最終執(zhí)行完畢返回可以分為下面三個過程:

  • 詞法和語義解析
  • 優(yōu)化sql語句,制定執(zhí)行計劃
  • 執(zhí)行并返回結果

我們把這種普通語句稱作Immediate Statements。  

但是很多情況,我們的一條sql語句可能會反復執(zhí)行,或者每次執(zhí)行的時候只有個別的值不同(比如query的where子句值不同,update的set子句值不同,insert的values值不同)。

如果每次都需要經過上面的詞法語義解析、語句優(yōu)化、制定執(zhí)行計劃等,則效率就明顯不行了。

所謂預編譯語句就是將這類語句中的值用占位符替代,可以視為將sql語句模板化或者說參數化,一般稱這類語句叫Prepared Statements或者Parameterized Statements

預編譯語句的優(yōu)勢在于歸納為:一次編譯、多次運行,省去了解析優(yōu)化等過程;此外預編譯語句能防止sql注入。

當然就優(yōu)化來說,很多時候最優(yōu)的執(zhí)行計劃不是光靠知道sql語句的模板就能決定了,往往就是需要通過具體值來預估出成本代價。

1.2:MySQL的預編譯功能

注意MySQL的老版本(4.1之前)是不支持服務端預編譯的,但基于目前業(yè)界生產環(huán)境普遍情況,基本可以認為MySQL支持服務端預編譯。

下面我們來看一下MySQL中預編譯語句的使用。

(1)建表

首先我們有一張測試表t,結構如下所示:

?
1
2
3
4
5
6
7
8
mysql> show create table t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `a` int(11) DEFAULT NULL,
  `b` varchar(20) DEFAULT NULL,
  UNIQUE KEY `ab` (`a`,`b`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

(2)編譯

我們接下來通過 PREPARE stmt_name FROM preparable_stm的語法來預編譯一條sql語句

?
1
2
3
mysql> prepare ins from 'insert into t select ?,?';
Query OK, 0 rows affected (0.00 sec)
Statement prepared

(3)執(zhí)行

我們通過EXECUTE stmt_name [USING @var_name [, @var_name] ...]的語法來執(zhí)行預編譯語句

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> set @a=999,@b='hello';
Query OK, 0 rows affected (0.00 sec)
 
mysql> execute ins using @a,@b;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0
 
mysql> select * from t;
+------+-------+
| a    | b     |
+------+-------+
|  999 | hello |
+------+-------+
1 row in set (0.00 sec)

可以看到,數據已經被成功插入表中。

MySQL中的預編譯語句作用域是session級,但我們可以通過max_prepared_stmt_count變量來控制全局最大的存儲的預編譯語句。

?
1
2
3
4
5
mysql> set @@global.max_prepared_stmt_count=1;
Query OK, 0 rows affected (0.00 sec)
 
mysql> prepare sel from 'select * from t';
ERROR 1461 (42000): Can't create more than max_prepared_stmt_count statements (current value: 1)

當預編譯條數已經達到閾值時可以看到MySQL會報如上所示的錯誤。

(4)釋放

如果我們想要釋放一條預編譯語句,則可以使用{DEALLOCATE | DROP} PREPARE stmt_name的語法進行操作:

?
1
2
mysql> deallocate prepare ins;
Query OK, 0 rows affected (0.00 sec)

六:為什么PrepareStatement可以防止sql注入

原理是采用了預編譯的方法,先將SQL語句中可被客戶端控制的參數集進行編譯,生成對應的臨時變量集,再使用對應的設置方法,為臨時變量集里面的元素進行賦值,賦值函數setString(),會對傳入的參數進行強制類型檢查和安全檢查,所以就避免了SQL注入的產生。下面具體分析

(1):為什么Statement會被sql注入

因為Statement之所以會被sql注入是因為SQL語句結構發(fā)生了變化。比如:

?
1
"select*from tablename where username='"+uesrname+"'and password='"+password+"'"

在用戶輸入'or true or'之后sql語句結構改變。

?
1
select * from tablename where username=''or true or'' and password=''

這樣本來是判斷用戶名和密碼都匹配時才會計數,但是經過改變后變成了或的邏輯關系,不管用戶名和密碼是否匹配該式的返回值永遠為true;

(2)為什么Preparement可以防止SQL注入。

因為Preparement樣式為

?
1
select * from tablename where username=? and password=?

該SQL語句會在得到用戶的輸入之前先用數據庫進行預編譯,這樣的話不管用戶輸入什么用戶名和密碼的判斷始終都是并的邏輯關系,防止了SQL注入

簡單總結,參數化能防注入的原因在于,語句是語句,參數是參數,參數的值并不是語句的一部分,數據庫只按語句的語義跑,至于跑的時候是帶一個普通背包還是一個怪物,不會影響行進路線,無非跑的快點與慢點的區(qū)別。

七:mybatis是如何防止SQL注入的  

首先看一下下面兩個sql語句的區(qū)別:

?
1
2
3
4
5
6
<select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap">
select id, username, password, role
from user
where username = #{username,jdbcType=VARCHAR}
and password = #{password,jdbcType=VARCHAR}
</select>
?
1
2
3
4
5
6
<select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap">
select id, username, password, role
from user
where username = ${username,jdbcType=VARCHAR}
and password = ${password,jdbcType=VARCHAR}
</select>

mybatis中的#和$的區(qū)別:

  • 1、#將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。
    如:where username=#{username},如果傳入的值是111,那么解析成sql時的值為where username="111", 如果傳入的值是id,則解析成的sql為where username="id". 
  • 2、$將傳入的數據直接顯示生成在sql中。
    如:where username=${username},如果傳入的值是111,那么解析成sql時的值為where username=111;
    如果傳入的值是;drop table user;,則解析成的sql為:select id, username, password, role from user where username=;drop table user;
  • 3、#方式能夠很大程度防止sql注入,$方式無法防止Sql注入。
  • 4、$方式一般用于傳入數據庫對象,例如傳入表名.
  • 5、一般能用#的就別用$,若不得不使用“${xxx}”這樣的參數,要手工地做好過濾工作,來防止sql注入攻擊。
  • 6、在MyBatis中,“${xxx}”這樣格式的參數會直接參與SQL編譯,從而不能避免注入攻擊。但涉及到動態(tài)表名和列名時,只能使用“${xxx}”這樣的參數格式。所以,這樣的參數需要我們在代碼中手工進行處理來防止注入。

【結論】在編寫MyBatis的映射語句時,盡量采用“#{xxx}”這樣的格式。若不得不使用“${xxx}”這樣的參數,要手工地做好過濾工作,來防止SQL注入攻擊。

mybatis是如何做到防止sql注入的

MyBatis框架作為一款半自動化的持久層框架,其SQL語句都要我們自己手動編寫,這個時候當然需要防止SQL注入。其實,MyBatis的SQL是一個具有“輸入+輸出”的功能,類似于函數的結構,參考上面的兩個例子。其中,parameterType表示了輸入的參數類型,resultType表示了輸出的參數類型。回應上文,如果我們想防止SQL注入,理所當然地要在輸入參數上下功夫。上面代碼中使用#的即輸入參數在SQL中拼接的部分,傳入參數后,打印出執(zhí)行的SQL語句,會看到SQL是這樣的:

?
1
select id, username, password, role from user where username=? and password=?

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

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

參考資料:

http://www.jfrwli.cn/article/212808.html

http://www.jfrwli.cn/article/221201.html

到此這篇關于SQL注入詳解及防范方法的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://www.cnblogs.com/myseries/p/10821372.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 亚洲国产综合在线 | 自拍视频在线 | 午夜精品久久久久久久久久久久久 | 欧美大成色www永久网站婷 | 亚洲一级毛片 | 很黄很色很爽的视频 | 久久久精品在线 | 欧美日韩在线免费观看 | 欧美激情一区 | 亚洲一区二区视频 | 四房婷婷 | 欧美一区二区三区在线观看视频 | 自拍偷拍第一页 | 精品伊人久久 | 午夜影院 | 日韩精品成人 | 欧美一区二区三区在线观看视频 | 久久精品国产一区二区三 | 一级毛片在线播放 | 日本高清视频在线播放 | 三级在线观看网站 | 亚洲一区视频在线 | 亚洲免费在线观看 | 国产欧美精品一区二区色综合 | 在线一区二区三区 | 黄在线免费观看 | 亚洲欧美日韩一区 | 日韩免费一区 | 五月激情综合网 | 国产v亚洲v天堂无码 | 欧美一区二区精品 | 北条麻妃99精品青青久久 | 欧美激情精品久久久久久黑人 | 久久伊人精品 | 久久国产精品视频 | 性色视频在线 | 免费观看一区二区三区毛片 | 亚洲男人在线天堂 | 亚洲国产成人av | 亚洲综合一二区 | 爱综合|