W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
SQL注入攻擊(SQL Injection),簡(jiǎn)稱(chēng)注入攻擊,是Web開(kāi)發(fā)中最常見(jiàn)的一種安全漏洞??梢杂盟鼇?lái)從數(shù)據(jù)庫(kù)獲取敏感信息,或者利用數(shù)據(jù)庫(kù)的特性執(zhí)行添加用戶(hù),導(dǎo)出文件等一系列惡意操作,甚至有可能獲取數(shù)據(jù)庫(kù)乃至系統(tǒng)用戶(hù)最高權(quán)限。
而造成SQL注入的原因是因?yàn)槌绦驔](méi)有有效過(guò)濾用戶(hù)的輸入,使攻擊者成功的向服務(wù)器提交惡意的SQL查詢(xún)代碼,程序在接收后錯(cuò)誤的將攻擊者的輸入作為查詢(xún)語(yǔ)句的一部分執(zhí)行,導(dǎo)致原始的查詢(xún)邏輯被改變,額外的執(zhí)行了攻擊者精心構(gòu)造的惡意代碼。
很多Web開(kāi)發(fā)者沒(méi)有意識(shí)到SQL查詢(xún)是可以被篡改的,從而把SQL查詢(xún)當(dāng)作可信任的命令。殊不知,SQL查詢(xún)是可以繞開(kāi)訪問(wèn)控制,從而繞過(guò)身份驗(yàn)證和權(quán)限檢查的。更有甚者,有可能通過(guò)SQL查詢(xún)?nèi)ミ\(yùn)行主機(jī)系統(tǒng)級(jí)的命令。
下面將通過(guò)一些真實(shí)的例子來(lái)詳細(xì)講解SQL注入的方式。
考慮以下簡(jiǎn)單的登錄表單:
<form action="/login" method="POST">
<p>Username: <input type="text" name="username" /></p>
<p>Password: <input type="password" name="password" /></p>
<p><input type="submit" value="登陸" /></p>
</form>
我們的處理里面的SQL可能是這樣的:
username:=r.Form.Get("username")
password:=r.Form.Get("password")
sql:="SELECT * FROM user WHERE username='"+username+"' AND password='"+password+"'"
如果用戶(hù)的輸入的用戶(hù)名如下,密碼任意
myuser' or 'foo' = 'foo' --
那么我們的SQL變成了如下所示:
SELECT * FROM user WHERE username='myuser' or 'foo'=='foo' --'' AND password='xxx'
在SQL里面--
是注釋標(biāo)記,所以查詢(xún)語(yǔ)句會(huì)在此中斷。這就讓攻擊者在不知道任何合法用戶(hù)名和密碼的情況下成功登錄了。
對(duì)于MSSQL還有更加危險(xiǎn)的一種SQL注入,就是控制系統(tǒng),下面這個(gè)可怕的例子將演示如何在某些版本的MSSQL數(shù)據(jù)庫(kù)上執(zhí)行系統(tǒng)命令。
sql:="SELECT * FROM products WHERE name LIKE '%"+prod+"%'"
Db.Exec(sql)
如果攻擊提交a%' exec master..xp_cmdshell 'net user test testpass /ADD' --
作為變量 prod的值,那么sql將會(huì)變成
sql:="SELECT * FROM products WHERE name LIKE '%a%' exec master..xp_cmdshell 'net user test testpass /ADD'--%'"
MSSQL服務(wù)器會(huì)執(zhí)行這條SQL語(yǔ)句,包括它后面那個(gè)用于向系統(tǒng)添加新用戶(hù)的命令。如果這個(gè)程序是以sa運(yùn)行而 MSSQLSERVER服務(wù)又有足夠的權(quán)限的話(huà),攻擊者就可以獲得一個(gè)系統(tǒng)帳號(hào)來(lái)訪問(wèn)主機(jī)了。
雖然以上的例子是針對(duì)某一特定的數(shù)據(jù)庫(kù)系統(tǒng)的,但是這并不代表不能對(duì)其它數(shù)據(jù)庫(kù)系統(tǒng)實(shí)施類(lèi)似的攻擊。針對(duì)這種安全漏洞,只要使用不同方法,各種數(shù)據(jù)庫(kù)都有可能遭殃。
也許你會(huì)說(shuō)攻擊者要知道數(shù)據(jù)庫(kù)結(jié)構(gòu)的信息才能實(shí)施SQL注入攻擊。確實(shí)如此,但沒(méi)人能保證攻擊者一定拿不到這些信息,一旦他們拿到了,數(shù)據(jù)庫(kù)就存在泄露的危險(xiǎn)。如果你在用開(kāi)放源代碼的軟件包來(lái)訪問(wèn)數(shù)據(jù)庫(kù),比如論壇程序,攻擊者就很容易得到相關(guān)的代碼。如果這些代碼設(shè)計(jì)不良的話(huà),風(fēng)險(xiǎn)就更大了。目前Discuz、phpwind、phpcms等這些流行的開(kāi)源程序都有被SQL注入攻擊的先例。
這些攻擊總是發(fā)生在安全性不高的代碼上。所以,永遠(yuǎn)不要信任外界輸入的數(shù)據(jù),特別是來(lái)自于用戶(hù)的數(shù)據(jù),包括選擇框、表單隱藏域和 cookie。就如上面的第一個(gè)例子那樣,就算是正常的查詢(xún)也有可能造成災(zāi)難。
SQL注入攻擊的危害這么大,那么該如何來(lái)防治呢?下面這些建議或許對(duì)防治SQL注入有一定的幫助。
text/template
包里面的HTMLEscapeString
函數(shù)可以對(duì)字符串進(jìn)行轉(zhuǎn)義處理。database/sql
里面的查詢(xún)函數(shù)Prepare
和Query
,或者Exec(query string, args ...interface{})
。通過(guò)上面的示例我們可以知道,SQL注入是危害相當(dāng)大的安全漏洞。所以對(duì)于我們平常編寫(xiě)的Web應(yīng)用,應(yīng)該對(duì)于每一個(gè)小細(xì)節(jié)都要非常重視,細(xì)節(jié)決定命運(yùn),生活如此,編寫(xiě)Web應(yīng)用也是這樣。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: