<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          什么是SQL 注入?

          共 3149字,需瀏覽 7分鐘

           ·

          2020-09-23 02:38

          來源:jizhi.im/blog/post/sql_injection_intro


          文章目錄:

          • 何謂SQL注入?

          • SQL數(shù)據(jù)庫操作示例

          • SQL數(shù)據(jù)庫注入示例

          • 如何防止SQL注入問題

          • SQL數(shù)據(jù)庫反注入示例

          何謂SQL注入?

          SQL注入是一種非常常見的數(shù)據(jù)庫攻擊手段,SQL注入漏洞也是網(wǎng)絡(luò)世界中最普遍的漏洞之一。大家也許都聽過某某學(xué)長(zhǎng)通過攻擊學(xué)校數(shù)據(jù)庫修改自己成績(jī)的事情,這些學(xué)長(zhǎng)們一般用的就是SQL注入方法。

          SQL注入其實(shí)就是惡意用戶通過在表單中填寫包含SQL關(guān)鍵字的數(shù)據(jù)來使數(shù)據(jù)庫執(zhí)行非常規(guī)代碼的過程。簡(jiǎn)單來說,就是數(shù)據(jù)「越俎代庖」做了代碼才能干的事情。這個(gè)問題的來源是,SQL數(shù)據(jù)庫的操作是通過SQL語句來執(zhí)行的,而無論是執(zhí)行代碼還是數(shù)據(jù)項(xiàng)都必須寫在SQL語句之中,這就導(dǎo)致如果我們?cè)跀?shù)據(jù)項(xiàng)中加入了某些SQL語句關(guān)鍵字(比如說SELECT、DROP等等),這些關(guān)鍵字就很可能在數(shù)據(jù)庫寫入或讀取數(shù)據(jù)時(shí)得到執(zhí)行。

          多言無益,我們拿真實(shí)的案例來說話。下面我們先使用SQLite建立一個(gè)學(xué)生檔案表。

          SQL數(shù)據(jù)庫操作示例

          import?sqlite3

          #?連接數(shù)據(jù)庫
          conn?=?sqlite3.connect('test.db')

          #?建立新的數(shù)據(jù)表
          conn.executescript('''DROP?TABLE?IF?EXISTS?students;
          ???????CREATE?TABLE?students
          ???????(id?INTEGER?PRIMARY?KEY?AUTOINCREMENT,
          ???????name?TEXT?NOT?NULL);'''
          )


          #?插入學(xué)生信息
          students?=?['Paul','Tom','Tracy','Lily']

          for?name?in?students:
          ????query?=?"INSERT?INTO?students?(name)?VALUES?('%s')"?%?(name)
          ????conn.executescript(query);

          #?檢視已有的學(xué)生信息
          cursor?=?conn.execute("SELECT?id,?name?from?students")
          print('IDName')
          for?row?in?cursor:
          ????print('{0}{1}'.format(row[0],?row[1]))

          conn.close()

          點(diǎn)擊運(yùn)行按鈕將會(huì)打印目前表中的內(nèi)容。上述程序中我們建立了一個(gè)test.db數(shù)據(jù)庫以及一個(gè)students數(shù)據(jù)表,并向表中寫入了四條學(xué)生信息。

          那么SQL注入又是怎么一回事呢?我們嘗試再插入一條惡意數(shù)據(jù),數(shù)據(jù)內(nèi)容就是漫畫中的"Robert');DROP TABLE students;--",看看會(huì)發(fā)生什么情況。

          SQL數(shù)據(jù)庫注入示例

          conn?=?sqlite3.connect('test.db')

          #?插入包含注入代碼的信息
          name?=?"Robert');DROP?TABLE?students;--"
          query?=?"INSERT?INTO?students?(name)?VALUES?('%s')"?%?(name)

          conn.executescript(query)

          #?檢視已有的學(xué)生信息
          cursor?=?conn.execute("
          SELECT?id,?name?from?students")
          print('IDName')
          for?row?in?cursor:
          ????print('{0}{1}'.format(row[0],?row[1]))

          conn.close()

          你將會(huì)發(fā)現(xiàn),運(yùn)行后,程序沒有輸出任何數(shù)據(jù)內(nèi)容,而是返回一條錯(cuò)誤信息:表單students無法找到!

          這是為什么呢?問題就在于我們所插入的數(shù)據(jù)項(xiàng)中包含SQL關(guān)鍵字DROP TABLE,這兩個(gè)關(guān)鍵字的意義是從數(shù)據(jù)庫中清除一個(gè)表單。而關(guān)鍵字之前的Robert');使得SQL執(zhí)行器認(rèn)為上一命令已經(jīng)結(jié)束,從而使得危險(xiǎn)指令DROP TABLE得到執(zhí)行。也就是說,這段包含DROP TABLE關(guān)鍵字的數(shù)據(jù)項(xiàng)使得原有的簡(jiǎn)單的插入姓名信息的SQL語句

          "INSERT?INTO?students?(name)?VALUES?('Robert')"

          變?yōu)榱送瑫r(shí)包含另外一條清除表單命令的語句

          "INSERT?INTO?students?(name)?VALUES?('Robert');DROP?TABLE?students;--"

          而SQL數(shù)據(jù)庫執(zhí)行上述操作后,students表單被清除,因而表單無法找到,所有數(shù)據(jù)項(xiàng)丟失。

          如何防止SQL注入問題

          那么,如何防止SQL注入問題呢?

          大家也許都想到了,注入問題都是因?yàn)閳?zhí)行了數(shù)據(jù)項(xiàng)中的SQL關(guān)鍵字,那么,只要檢查數(shù)據(jù)項(xiàng)中是否存在SQL關(guān)鍵字不就可以了么?的確是這樣,很多數(shù)據(jù)庫管理系統(tǒng)都是采取了這種看似『方便快捷』的過濾手法,但是這并不是一種根本上的解決辦法,如果有個(gè)美國(guó)人真的就叫做『Drop Table』呢?你總不能逼人家改名字吧。

          合理的防護(hù)辦法有很多。首先,盡量避免使用常見的數(shù)據(jù)庫名和數(shù)據(jù)庫結(jié)構(gòu)。在上面的案例中,如果表單名字并不是students,則注入代碼將會(huì)在執(zhí)行過程中報(bào)錯(cuò),也就不會(huì)發(fā)生數(shù)據(jù)丟失的情況——SQL注入并不像大家想象得那么簡(jiǎn)單,它需要攻擊者本身對(duì)于數(shù)據(jù)庫的結(jié)構(gòu)有足夠的了解才能成功,因而在構(gòu)建數(shù)據(jù)庫時(shí)盡量使用較為復(fù)雜的結(jié)構(gòu)和命名方式將會(huì)極大地減少被成功攻擊的概率。

          使用正則表達(dá)式等字符串過濾手段限制數(shù)據(jù)項(xiàng)的格式、字符數(shù)目等也是一種很好的防護(hù)措施。理論上,只要避免數(shù)據(jù)項(xiàng)中存在引號(hào)、分號(hào)等特殊字符就能很大程度上避免SQL注入的發(fā)生。

          另外,就是使用各類程序文檔所推薦的數(shù)據(jù)庫操作方式來執(zhí)行數(shù)據(jù)項(xiàng)的查詢與寫入操作,比如在上述的案例中,如果我們稍加修改,首先使用execute()方法來保證每次執(zhí)行僅能執(zhí)行一條語句,然后將數(shù)據(jù)項(xiàng)以參數(shù)的方式與SQL執(zhí)行語句分離開來,就可以完全避免SQL注入的問題,如下所示:

          SQL數(shù)據(jù)庫反注入示例

          conn?=?sqlite3.connect('test.db')

          #?以安全方式插入包含注入代碼的信息
          name?=?"Robert');DROP?TABLE?students;--"
          query?=?"INSERT?INTO?students?(name)?VALUES?(?)"

          conn.execute(query,?[name])

          #?檢視已有的學(xué)生信息
          cursor?=?conn.execute("
          SELECT?id,?name?from?students")
          print('IDName')
          for?row?in?cursor:
          ????print('{0}{1}'.format(row[0],?row[1]))

          conn.close()

          而對(duì)于PHP而言,則可以通過mysql_real_escape_string等方法對(duì)SQL關(guān)鍵字進(jìn)行轉(zhuǎn)義,必要時(shí)審查數(shù)據(jù)項(xiàng)目是否安全來防治SQL注入。

          當(dāng)然,做好數(shù)據(jù)庫的備份,同時(shí)對(duì)敏感內(nèi)容進(jìn)行加密永遠(yuǎn)是最重要的。某些安全性問題可能永遠(yuǎn)不會(huì)有完美的解決方案,只有我們做好最基本的防護(hù)措施,才能在發(fā)生問題的時(shí)候亡羊補(bǔ)牢,保證最小程度的損失。

          推薦閱讀

          InnoDB索引允許NULL對(duì)性能有影響嗎

          Mysql的binlog和relay-log到底長(zhǎng)啥樣?

          漲姿勢(shì):為啥MySQL官方不推薦使用uuid或者雪花id作為主鍵?

          瀏覽 69
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色哟哟精品| 国产无码一区二区三区视频 | 亚洲日韩在线专区 | 蜜桃精品视频 | 北条麻妃无码精品 |