sql防注入-九游会j9娱乐平台
a. 什麼是sql注入,怎麼防止sql注入
原理
sql注入攻擊指的是通過構建特殊的輸入作為參數傳入web應用程序,而這些輸入大都是sql語法里的一些組合,通過執行sql語句進而執行攻擊者所要的操作,其主要原因是程序沒有細致地過濾用戶輸入的數據,致使非法數據侵入系統。
根據相關技術原理,sql注入可以分為平台層注入和代碼層注入。前者由不安全的資料庫配置或資料庫平台的漏洞所致;後者主要是由於程序員對輸入未進行細致地過濾,從而執行了非法的數據查詢。基於此,sql注入的產生原因通常表現在以下幾方面:①不當的類型處理;②不安全的資料庫配置;③不合理的查詢集處理;④不當的錯誤處理;⑤轉義字元處理不合適;⑥多個提交處理不當。
攻擊
當應用程序使用輸入內容來構造動態sql語句以訪問資料庫時,會發生sql注入攻擊。如果代碼使用存儲過程,而這些存儲過程作為包含未篩選的用戶輸入的字元串來傳遞,也會發生sql注入。sql注入可能導致攻擊者使用應用程序登陸在資料庫中執行命令。相關的sql注入可以通過測試工具pangolin進行。如果應用程序使用特權過高的帳戶連接到資料庫,這種問題會變得很嚴重。在某些表單中,用戶輸入的內容直接用來構造動態sql命令,或者作為存儲過程的輸入參數,這些表單特別容易受到sql注入的攻擊。而許多網站程序在編寫時,沒有對用戶輸入的合法性進行判斷或者程序中本身的變數處理不當,使應用程序存在安全隱患。這樣,用戶就可以提交一段資料庫查詢的代碼,根據程序返回的結果,獲得一些敏感的信息或者控制整個伺服器,於是sql注入就發生了。
防護
歸納一下,主要有以下幾點:
1.永遠不要信任用戶的輸入。對用戶的輸入進行校驗,可以通過正則表達式,或限制長度;對單引號和
雙"-"進行轉換等。
2.永遠不要使用動態拼裝sql,可以使用參數化的sql或者直接使用存儲過程進行數據查詢存取。
3.永遠不要使用管理員許可權的資料庫連接,為每個應用使用單獨的許可權有限的資料庫連接。
4.不要把機密信息直接存放,加密或者hash掉密碼和敏感的信息。
5.應用的異常信息應該給出盡可能少的提示,最好使用自定義的錯誤信息對原始錯誤信息進行包裝
6.sql注入的檢測方法一般採取輔助軟體或網站平台來檢測,軟體一般採用sql注入檢測工具jsky,網站平台就有億思網站安全平台檢測工具。mdcsoft scan等。採用mdcsoft-ips可以有效的防禦sql注入,xss攻擊等。
b. 如何防止sql注入
一、存儲程序
在學習資料庫視頻的時候接觸過,它是存儲在資料庫中的一些事先編譯好的指令。在用的時候不用重新編寫,直接調用就好了。所以,使用它可以大大提高程序的執行效率。
那麼,如何創建一個存儲程序並使用它呢?這是我們今天要解決的問題。
1.創建過程
可編程性——下拉菜單——存儲過程——右鍵——查詢菜單———指定模板參數的值——新建查詢——輸入語句——查詢菜單中的分析檢查語法是否正確——執行
2.具體創建語法
在創建存儲程序時,為了應對各種變換的數據,通常會涉及到帶參數的存儲程序,其中參數用@來表示。
create procere procerename[:number] --[:number]表示一組存儲程序中的第幾個,如果只有一個,此參數可忽略
[@parameter data_type] [default] [output] --@parameter表示存儲過程中的參數,default 表示默認值,output表示輸出值即輸出值 as sqlstatement --[]代表可選參數
3.具體執行過程
exec[ute] procerename [參數]
舉例:
--創建
createprocere
scores @score1smallint, @score2smallint, @score3smallint,
@score4smallint, @score5smallint, @myavgsmallint output
--output可用return來代替
as select @myavg=(@score1 @score2 @score3 @score4 @score5)/5 --調用過程
declare@avgscore smallint --將輸出結果放在avgscore中
execavgscore output 5,6,7,8,9, --帶有參數的存儲過程調用時,必須加上output關鍵字,否則sql會當做參數來對待
小結:存儲程序的創建可分為帶參數和不帶參數,以及含有默認值和輸出值得存儲程序,但是它們的使用原理是一樣的。只是帶輸出值得存儲程序在調用過程中要使用關鍵字output來對要輸出的變數進行聲明,否則sql會將它當做參數來處理。
注意:創建存儲程序後,我們可以在編寫程序時,直接調用存儲程序的名稱來代替復雜的查詢語句:
strsql="select ............;" strsql="execute procerename;"
二、參數化sql
是指在設計與資料庫鏈接並訪問數據時,在需要填入數值或數據的地方,使用參數 (parameter) 來給值,用@或?來表示參數。
在使用參數化查詢的情況下,資料庫伺服器不會將參數的內容視為sql指令的一部份來處理,而是在資料庫完成 sql 指令的編譯後,才套用參數運行,因此就算參數中含有惡意的指令,由於已經編譯完成,就不會被資料庫所運行,因此,可從一定程度上避免sql注入。
參數化sql在不同資料庫中支持的方式有一定的差別。sql server中二者均支持。
在不用的資料庫上基本語法都是一樣的,但在不同的運行平台上客戶端的書寫有不同之處,在這里就拿現在我正在學習的sql server在.net上執行來舉例。
--sql
server中的參數化sql語句: select * from mytable where myid = @myid insert into
mytable (c1, c2, c3, c4) values (@c1, @c2, @c3, @c4)'.在.net上執行
sqlcommand sqlcmd = new sqlcommand("insert into mytable (c1, c2, c3, c4) values (@c1, @c2, @c3, @c4)", sqlconn);
sqlcmd.parameters.addwithvalue("@c1", 1); ' 設定參數 @c1 的值。
sqlcmd.parameters.addwithvalue("@c2", 2); ' 設定參數 @c2 的值。
sqlcmd.parameters.addwithvalue("@c3", 3); ' 設定參數 @c3 的值。
sqlcmd.parameters.addwithvalue("@c4", 4); ' 設定參數 @c4 的值。
sqlconn.open();
sqlcmd.executenonquery();
sqlconn.close();
在向command中增加參數時,還有其他的方法,如:
sqlcmd.parameters.add("@c1",sqldbtype.bigint) 'bigint為c1的數據類型
sqlcmd.parameter("@c1").value=1 '設定值
三、regular expression
簡稱res是一種非常強大的文字驗證技術。通常我們在設計程序時,如果要在text中輸入數字的話,那麼我們會用到isnumberic函數來限制,但是
很多情況,為了用戶方便,我們不止要用到限定數字這一個技術,還有很多關系式需要我們去遵循,如手機號碼要限定成11為,郵箱號碼要限制相應的格式等。這
時候就用到了res這種技術。它可以為我們要輸入的內容提供一個模板,讓用戶的輸入必須遵循這個模板的格式,如果格式不正確,則程序不能繼續執行。這樣也
可以避免sql注入。
例如
\d -------代表數字
\d{5} -------代表5位數字
\w @\w -------@前的w 表示要有至少一個的字元,@代表這個模板中必須有一個@字元。
當然在使用這種技術之前,是有條件的,首先,它需要引用一個命名空間,具體如下:
imports re=system.text.regularexpressions.regex
這樣還不夠,我們需要一個方法來做驗證用戶輸入是否正確的工作,這里,我們要用到一個方法match,具體使用如下:
dim input,pattern as string
input=me.txtinput.texttrim()
pattern=me.txtpattern.text
if re.mathc(input,pattern).success then 『使用match方法來對用戶輸入的內容與定義好的模板進行驗證
messagebox.show("true,input matches pattern") else messagebox.show("false,input does not match pattern") end if
以上,是通過看.net視頻總結出來的避免sql注入的三種方法,由於對專業知識了解有限,具體原理並不清楚,有待以後深入學習後總結。
c. 如何能防止sql注入
如何能防止sql注入
普通用戶與系統管理員用戶的許可權要有嚴格的區分。
如果一個普通用戶在使用查詢語句中嵌入另一個drop table語句,那麼是否允許執行呢?由於drop語句關繫到資料庫的基本對象,故要操作這個語句用戶必須有相關的許可權。在許可權設計中,對於終端用戶,即應用軟體的使用者,沒有必要給他們資料庫對象的建立、刪除等許可權。那麼即使在他們使用sql語句中帶有嵌入式的惡意代碼,由於其用戶許可權的限制,這些代碼也將無法被執行。故應用程序在設計的時候,
強迫使用參數化語句。
如果在編寫sql語句的時候,用戶輸入的變數不是直接嵌入到sql語句。而是通過參數來傳遞這個變數的話,那麼就可以有效的防治sql注入式攻擊。也就是說,用戶的輸入絕對不能夠直接被嵌入到sql語句中。與此相反,用戶的輸入的內容必須進行過濾,或者使用參數化的語句來傳遞用戶輸入的變數。參數化的語句使用參數而不是將用戶輸入變數嵌入到sql語句中。採用這種措施,可以杜絕大部分的sql注入式攻擊。不過可惜的是,現在支持參數化語句的資料庫引擎並不多。不過資料庫工程師在開發產品的時候要盡量採用參數化語句。
多多使用sql server資料庫自帶的安全參數。
為了減少注入式攻擊對於sql server資料庫的不良影響,在sqlserver資料庫專門設計了相對安全的sql參數。在資料庫設計過程中,工程師要盡量採用這些參數來杜絕惡意的sql注入式攻擊。
如在sql server資料庫中提供了parameters集合。這個集合提供了類型檢查和長度驗證的功能。如果管理員採用了parameters這個集合的話,則用戶輸入的內容將被視為字元值而不是可執行代碼。即使用戶輸入的內容中含有可執行代碼,則資料庫也會過濾掉。因為此時資料庫只把它當作普通的字元來處理。使用parameters集合的另外一個優點是可以強制執行類型和長度檢查,范圍以外的值將觸發異常。如果用戶輸入的值不符合指定的類型與長度約束,就會發生異常,並報告給管理員。如上面這個案例中,如果員工編號定義的數據類型為字元串型,長度為10個字元。而用戶輸入的內容雖然也是字元類型的數據,但是其長度達到了20個字元。則此時就會引發異常,因為用戶輸入的內容長度超過了資料庫欄位長度的限制。
加強對用戶輸入的驗證。
總體來說,防治sql注入式攻擊可以採用兩種方法,一是加強對用戶輸入內容的檢查與驗證;二是強迫使用參數化語句來傳遞用戶輸入的內容。在sqlserver資料庫中,有比較多的用戶輸入內容驗證工具,可以幫助管理員來對付sql注入式攻擊。測試字元串變數的內容,只接受所需的值。拒絕包含二進制數據、轉義序列和注釋字元的輸入內容。這有助於防止腳本注入,防止某些緩沖區溢出攻擊。測試用戶輸入內容的大小和數據類型,強制執行適當的限制與轉換。這即有助於防止有意造成的緩沖區溢出,對於防治注入式攻擊有比較明顯的效果。
如可以使用存儲過程來驗證用戶的輸入。利用存儲過程可以實現對用戶輸入變數的過濾,如拒絕一些特殊的符號。如以上那個惡意代碼中,只要存儲過程把那個分號過濾掉,那麼這個惡意代碼也就沒有用武之地了。在執行sql語句之前,可以通過資料庫的存儲過程,來拒絕接納一些特殊的符號。在不影響資料庫應用的前提下,應該讓資料庫拒絕包含以下字元的輸入。如分號分隔符,它是sql注入式攻擊的主要幫凶。如注釋分隔符。注釋只有在數據設計的時候用的到。一般用戶的查詢語句中沒有必要注釋的內容,故可以直接把他拒絕掉,通常情況下這么做不會發生意外損失。把以上這些特殊符號拒絕掉,那麼即使在sql語句中嵌入了惡意代碼,他們也將毫無作為。
故始終通過測試類型、長度、格式和范圍來驗證用戶輸入,過濾用戶輸入的內容。這是防止sql注入式攻擊的常見並且行之有效的措施。
多層環境如何防治sql注入式攻擊?
在多層應用環境中,用戶輸入的所有數據都應該在驗證之後才能被允許進入到可信區域。未通過驗證過程的數據應被資料庫拒絕,並向上一層返回一個錯誤信息。實現多層驗證。對無目的的惡意用戶採取的預防措施,對堅定的攻擊者可能無效。更好的做法是在用戶界面和所有跨信任邊界的後續點上驗證輸入。如在客戶端應用程序中驗證數據可以防止簡單的腳本注入。但是,如果下一層認為其輸入已通過驗證,則任何可以繞過客戶端的惡意用戶就可以不受限制地訪問系統。故對於多層應用環境,在防止注入式攻擊的時候,需要各層一起努力,在客戶端與資料庫端都要採用相應的措施來防治sql語句的注入式攻擊。
d. 如何防止sql注入
sql注入其實就是在這些不安全控制項內輸入sql或其他資料庫的一些語句,從而達到欺騙伺服器執行惡意到嗎影響到資料庫的數據。防止sql注入,可以在接受不安全空間的內容時過濾掉接受字元串內的「'」,那麼他不再是一條sql語句,而是一個類似sql語句的zifuc,執行後也不會對資料庫有破壞。
如:-----下面這一段是找的
username = request("username") //獲取用戶名 這里是通過url傳值獲取的
password = request("password") //獲取密碼 也是通過url傳值獲取的
sql="select * from userlist where username = '" & username & "' and password = '" & password & "'"--------如果某個人知道某個用戶名是admin,常常有人網站的管理員用戶名就是admin,這是密碼可以選用'or 1 or ',
那麼sql="select * from userlist where username = 'admin' and password = '' or 1 or ''",顯然1是恆真的,那麼驗證密碼就通過了。補充:
防止的方式比較多,比如可以限制username,password中出現"'"這些字元,一般網站都是只允許數字,字元,下劃線的組合,這可以通過javascript驗證。也可以採取用存儲過程代替sql拼接,等等。
e. 如何徹底防止sql注入
1、對,限制用戶輸入肯定有效
2、應該也可以做到,但正則不是一種高效的方法,用htmlencode的方法可以有效防止空格等被dbms解釋,但注意別把編碼、解碼搞反了;存儲過程是dbms執行的一段程序,把數據操縱交給存儲過程執行,而不是提交sql語句,可以有效防止sql注入。
3、地址欄的sql攻擊,下面我引用了一段資料解釋,他關於機制說的較清楚,關於解決,只是從客戶端考慮的,實際上用存儲過程等都可以防範。
資料:
首先,入侵者會對一個網站確定可不可以進行注入,假設一篇文章的地址為:http://www.naohou.cn/show.asp?id=325一般會以提交兩個地址來測試,如:
http://www.naohou.cn/show.asp?id=325 and 1=1
http://www.naohou.cn/show.asp?id=325 and 1=2
第一個地址後面加了 and 1=1,構成的sql語句也就變為了:select * from 表單名 where id=1 and 1=1這句話要成立就必須and前後語句都成立。那麼前面的文章地址是可以訪問的,後面的1=1也是客觀成立的,那麼第一個地址就可以正常顯示;相反1=2是顯然不成立的,關鍵就看這步了,如果提交and 1=2頁面還是正常顯示說明他並沒有將and 1=2寫入sql語句,此站也就不存在注入漏洞;但如果提交and 1=2之後返回了錯誤頁面則說明此站點將後面的語句帶入了sql語句並執行了,也就說明他可以進行sql注入。(註:如果地址後面跟的是news.asp?id='1'就得變為news.asp?id=1' and '1'='1來補全引號了)
那麼,知道可以注入後入侵者可以做什麼呢?
這里就簡單的說一下,比如提交這樣的地址:
http://www.naohou.cn/show.asp?id=325 and exists (select * from 表名 where 列名=數據)
根據返回的正確或錯誤頁面來判斷猜的表名和列名是否正確,具體實現時是先猜表名再猜列名。當猜出表名和列名之後還可以用asc和mid函數來猜出各列的數據。mid函數的格式為:mid(變數名,第幾個字元開始讀取,讀取幾個字元),比如:mid(pwd,1,2)就可以從變數pwd中的第一位開始讀取兩位的字元。asc函數的格式為:asc("字元串"),如:asc("a")就可以讀出字母a的ascii碼了。那麼實際應用的時候就可以寫為:asc(mid(pwd,1,1))這樣讀取的就是pwd列的第一個字元的ascii碼,提交: asc(mid(pwd,1,1))>97以返回的頁面是否為正確頁面來判斷pwd列的第一個字元的ascii碼是否大於97(a的ascii碼),如果正確就再試是否小於122(z的ascii碼)……這樣慢慢縮小字元的ascii碼的范圍,猜到真實的ascii碼也只是時間的問題。一位一位的猜就可以得到資料庫中的用戶名和密碼了。還有一種asp驗證缺陷——就是用戶名和密碼都輸'or '1'='1,構造sql語句select * form 表單名 where username='' or '1'='1' and pwd='' or '1'='1'就可以達到繞過密碼驗證的目的。
說了那麼多,其實防範的方法很簡單,我們把特殊字元(如and、or、'、")都禁止提交就可以防止注入了。asp傳輸數據分為get和post兩種, get是通過將數據添加到url後提交的方式,post則是利用郵寄信息數據欄位將數據傳送到伺服器。
f. 什麼是sql注入,如何防止sql注入
所謂sql注入,就是通過把sql命令插入到web表單提交或輸入域名或頁面請求的查詢字元串,最終達到欺騙伺服器執行惡意的sql命令。具體來說,它是利用現有應用程序,將(惡意)的sql命令注入到後台資料庫引擎執行的能力,它可以通過在web表單中輸入(惡意)sql語句得到一個存在安全漏洞的網站上的資料庫,而不是按照設計者意圖去執行sql語句。比如先前的很多影視網站泄露vip會員密碼大多就是通過web表單遞交查詢字元暴出的,這類表單特別容易受到sql注入式攻擊.
防護
歸納一下,主要有以下幾點:
1.永遠不要信任用戶的輸入。對用戶的輸入進行校驗,可以通過正則表達式,或限制長度;對單引號和
雙"-"進行轉換等。
2.永遠不要使用動態拼裝sql,可以使用參數化的sql或者直接使用存儲過程進行數據查詢存取。
3.永遠不要使用管理員許可權的資料庫連接,為每個應用使用單獨的許可權有限的資料庫連接。
4.不要把機密信息直接存放,加密或者hash掉密碼和敏感的信息。
5.應用的異常信息應該給出盡可能少的提示,最好使用自定義的錯誤信息對原始錯誤信息進行包裝
6.sql注入的檢測方法一般採取輔助軟體或網站平台來檢測,軟體一般採用sql注入檢測工具jsky,網站平台就有億思網站安全平台檢測工具。mdcsoft scan等。採用mdcsoft-ips可以有效的防禦sql注入,xss攻擊等。
g. 怎麼樣防止sql注入
(1)對於動態構造sql查詢的場合,可以使用下面的技術:
第一:替換單引號,即把所有單獨出現的單引號改成兩個單引號,防止攻擊者修改sql命令的含義。再來看前面的例子,「select * from users where login = ''' or ''1''=''1' and password = ''' or ''1''=''1'」顯然會得到與「select * from users where login = '' or '1'='1' and password = '' or '1'='1'」不同的結果。
第二:刪除用戶輸入內容中的所有連字元,防止攻擊者構造出類如「select * from users where login = 'mas' -- and password =''」之類的查詢,因為這類查詢的後半部分已經被注釋掉,不再有效,攻擊者只要知道一個合法的用戶登錄名稱,根本不需要知道用戶的密碼就可以順利獲得訪問許可權。
第三:對於用來執行查詢的資料庫帳戶,限制其許可權。用不同的用戶帳戶執行查詢、插入、更新、刪除操作。由於隔離了不同帳戶可執行的操作,因而也就防止了原本用於執行select命令的地方卻被用於執行insert、update或delete命令。
⑵ 用存儲過程來執行所有的查詢。sql參數的傳遞方式將防止攻擊者利用單引號和連字元實施攻擊。此外,它還使得資料庫許可權可以限制到只允許特定的存儲過程執行,所有的用戶輸入必須遵從被調用的存儲過程的安全上下文,這樣就很難再發生注入式攻擊了。
⑶ 限製表單或查詢字元串輸入的長度。如果用戶的登錄名字最多隻有10個字元,那麼不要認可表單中輸入的10個以上的字元,這將大大增加攻擊者在sql命令中插入有害代碼的難度。
⑷ 檢查用戶輸入的合法性,確信輸入的內容只包含合法的數據。數據檢查應當在客戶端和伺服器端都執行——之所以要執行伺服器端驗證,是為了彌補客戶端驗證機制脆弱的安全性。
在客戶端,攻擊者完全有可能獲得網頁的源代碼,修改驗證合法性的腳本(或者直接刪除腳本),然後將非法內容通過修改後的表單提交給伺服器。因此,要保證驗證操作確實已經執行,唯一的辦法就是在伺服器端也執行驗證。你可以使用許多內建的驗證對象,例如regularexpressionvalidator,它們能夠自動生成驗證用的客戶端腳本,當然你也可以插入伺服器端的方法調用。如果找不到現成的驗證對象,你可以通過customvalidator自己創建一個。
⑸ 將用戶登錄名稱、密碼等數據加密保存。加密用戶輸入的數據,然後再將它與資料庫中保存的數據比較,這相當於對用戶輸入的數據進行了「消毒」處理,用戶輸入的數據不再對資料庫有任何特殊的意義,從而也就防止了攻擊者注入sql命令。system.web.security.formsauthentication類有一個,非常適合於對輸入數據進行消毒處理。
⑹ 檢查提取數據的查詢所返回的記錄數量。如果程序只要求返回一個記錄,但實際返回的記錄卻超過一行,那就當作出錯處理。
---------------------------------------------------------------------------------------------------------------------------
關鍵是明白原理,其實防範很簡單的,
1.過濾sql需要的參數中的敏感字元(注意加入忽略大小寫)
2.禁用資料庫伺服器的xp_cmdshell存儲過程,刪除相應用到的dll
3.屏蔽伺服器異常信息
h. sql防止注入代碼
<%
dim sql_injdata
sql_injdata = "'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare"
sql_inj = split(sql_injdata,"|")
if request.querystring<>"" then
for each sql_get in request.querystring
for sql_data=0 to ubound(sql_inj)
if instr(request.querystring(sql_get),sql_inj(sql_data))>0 then
response.write ""
response.end
end if
next
next
end if
if request.form<>"" then
for each sql_post in request.form
for sql_data=0 to ubound(sql_inj)
if instr(request.form(sql_post),sql_inj(sql_data))>0 then
response.write ""
response.end
end if
next
next
end if
%>
寫在資料庫連接文件中
i. 防止sql注入
如果使用.net,那就簡單了,可以用ado.net的參數化查詢。
例如:
sqlcommand cmd=new sqlcommand("select * from test where id=@id",conn);
cmd.parameters.addwithvalue("@id",sid);
cmd.executenonquery();
這個有很多種用法,詳細的內容需要對離線資料庫的概念進行理解