亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

來(lái)源:jizhi.im/blog/post/sql_injection_intro

先來(lái)看一副很有意思的漫畫:

相信大家對(duì)于學(xué)校們?cè)愀獾木W(wǎng)絡(luò)環(huán)境和運(yùn)維手段都早有體會(huì),在此就不多做吐槽了。今天我們來(lái)聊一聊SQL注入相關(guān)的內(nèi)容。

何謂SQL注入?

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

SQL注入 其實(shí)就是惡意用戶通過在表單中填寫包含SQL關(guān)鍵字的數(shù)據(jù)來(lái)使數(shù)據(jù)庫(kù)執(zhí)行非常規(guī)代碼的過程。簡(jiǎn)單來(lái)說(shuō),就是數(shù)據(jù)「越俎代庖」做了代碼才能干的事情。

這個(gè)問題的來(lái)源是,SQL數(shù)據(jù)庫(kù)的操作是通過SQL語(yǔ)句來(lái)執(zhí)行的,而無(wú)論是執(zhí)行代碼還是數(shù)據(jù)項(xiàng)都必須寫在SQL語(yǔ)句之中,這就導(dǎo)致如果我們?cè)跀?shù)據(jù)項(xiàng)中加入了某些SQL語(yǔ)句關(guān)鍵字(比如說(shuō)SELECT、DROP等等),這些關(guān)鍵字就很可能在數(shù)據(jù)庫(kù)寫入或讀取數(shù)據(jù)時(shí)得到執(zhí)行。

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

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

importsqlite3

連接數(shù)據(jù)庫(kù):

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

建立新的數(shù)據(jù)表:

conn.execute(''' DROPTABLEIFEXISTSstudents;

CREATETABLEstudents

( idINTEGERPRIMARY KEYAUTOINCREMENT,

nameTEXTNOTNULL);''')

插入學(xué)生信息:

students = [ 'Paul', 'Tom', 'Tracy', 'Lily']

forname instudents:

query = "INSERT INTO students (name) VALUES ('%s')"% (name)

conn.execute(query);

檢視已有的學(xué)生信息:

cursor= conn. execute( "SELECT id, name from students")

print( 'IDName')

forrow in cursor:

print( '{0}{1}'.format(row[ 0], row[ 1]))

conn. close

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

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

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

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

插入包含注入代碼的信息:

name = "Robert'); DROPTABLEstudents; --"

query = " INSERTINTOstudents ( name) VALUES( '%s') " % (name)

conn.execute(query)

檢視已有的學(xué)生信息:

cursor= conn. execute( "SELECT id, name from students")

print( 'IDName')

forrow in cursor:

print( '{0}{1}'.format(row[ 0], row[ 1]))

conn. close

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

這是為什么呢?問題就在于我們所插入的數(shù)據(jù)項(xiàng)中包含SQL關(guān)鍵字DROP TABLE,這兩個(gè)關(guān)鍵字的意義是從數(shù)據(jù)庫(kù)中清除一個(gè)表單。

而關(guān)鍵字之前的Robert');使得SQL執(zhí)行器認(rèn)為上一命令已經(jīng)結(jié)束,從而使得危險(xiǎn)指令DROP TABLE得到執(zhí)行。

也就是說(shuō),這段包含DROP TABLE關(guān)鍵字的數(shù)據(jù)項(xiàng)使得原有的簡(jiǎn)單的插入姓名信息的SQL語(yǔ)句:

INSERTINTOstudents ( name) VALUES( 'Robert')

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

INSERTINTOstudents ( name) VALUES( 'Robert'); DROPTABLEstudents;

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

如何防止SQL注入問題呢?

大家也許都想到了,注入問題都是因?yàn)閳?zhí)行了數(shù)據(jù)項(xiàng)中的SQL關(guān)鍵字,那么,只要檢查數(shù)據(jù)項(xiàng)中是否存在SQL關(guān)鍵字不就可以了么?

的確是這樣,很多數(shù)據(jù)庫(kù)管理系統(tǒng)都是采取了這種看似『方便快捷』的過濾手法,但是這并不是一種根本上的解決辦法,如果有個(gè)美國(guó)人真的就叫做『Drop Table』呢? 你總不能逼人家改名字吧。

合理的防護(hù)辦法有很多。首先,盡量避免使用常見的數(shù)據(jù)庫(kù)名和數(shù)據(jù)庫(kù)結(jié)構(gòu)。在上面的案例中,如果表單名字并不是students,則注入代碼將會(huì)在執(zhí)行過程中報(bào)錯(cuò),也就不會(huì)發(fā)生數(shù)據(jù)丟失的情況—— SQL注入 并不像大家想象得那么簡(jiǎn)單,它需要攻擊者本身對(duì)于數(shù)據(jù)庫(kù)的結(jié)構(gòu)有足夠的了解才能成功,因而在構(gòu)建數(shù)據(jù)庫(kù)時(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ù)庫(kù)操作方式來(lái)執(zhí)行數(shù)據(jù)項(xiàng)的查詢與寫入操作,比如在上述的案例中,如果我們稍加修改,首先使用execute方法來(lái)保證每次執(zhí)行僅能執(zhí)行一條語(yǔ)句,然后將數(shù)據(jù)項(xiàng)以參數(shù)的方式與SQL執(zhí)行語(yǔ)句分離開來(lái),就可以完全避免 SQL注入 的問題,如下SQL數(shù)據(jù)庫(kù)反注入示例。

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

以安全方式插入包含注入代碼的信息:

name = "Robert'); DROPTABLEstudents; --"

query = " INSERTINTOstudents ( name) VALUES(?) "

conn.execute(query, [name])

檢視已有的學(xué)生信息:

cursor= conn. execute( "SELECT id, name from students")

print( 'IDName')

forrow 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)目是否安全來(lái)防治 SQL注入 。

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

分享到:
標(biāo)簽:注入 SQL
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定