徐 昊
(廣東技術(shù)師范學(xué)院天河學(xué)院,廣東 廣州 510540)
SQL語句的應(yīng)用與研究
徐 昊
(廣東技術(shù)師范學(xué)院天河學(xué)院,廣東 廣州 510540)
本文從SQL的用法、規(guī)范、INTO子句、注入(Injection)4個方面來探討SQL語句在具體應(yīng)用中出現(xiàn)的效率低、安全差等問題,并給出相應(yīng)的策略,為后續(xù)進一步研究提供了有益的探索經(jīng)驗。
SQL;注入;安全
隨著網(wǎng)絡(luò)的廣泛應(yīng)用,基于B/S模式的應(yīng)用程序也越來越多。由于程序員的水平及經(jīng)驗也參差不齊,一部分程序員在編寫代碼的時候,不注意書寫規(guī)范、對用戶輸入數(shù)據(jù)的合法性不進行判斷,使得應(yīng)用程序執(zhí)行效率低,且存在網(wǎng)絡(luò)安全等問題。
查詢是關(guān)系數(shù)據(jù)庫中最基本的數(shù)據(jù)操作,通過SELE CT語句來實現(xiàn),其基本語法格式[1]:
SELE CT[ALL|DISTIN CT]字段列表
[INTO目標(biāo)數(shù)據(jù)表]
FROM源數(shù)據(jù)表[,…n]
[WHERE條件表達式]
[GROUP BY分組表達式]
[HAVING搜索表達式]
[ORDER BY排序表達式[,…n][AS C][DES C]]
[ CO MPUTE行聚合函數(shù)名(統(tǒng)計表達式)[,…n][BY分類表達式[,…n]]]
(1)*用法問題。對于初學(xué)者來說在編寫SQL語句程序時,為了圖方便,常用*來代替所有字段,經(jīng)常會出現(xiàn):Select *from…這樣的語句。這種語句的功能是顯示出表中的每一個字段的全部信息,包括不需要的信息也被顯示出來,這樣會消耗大量的內(nèi)存開銷、降低程序執(zhí)行效率;如果表中含有圖像、備注這樣類型的字段,會導(dǎo)致程序出錯無法正常運行。這種SQL寫法雖然在邏輯上是沒有問題,但往往在具體的實際應(yīng)用中由于這種不規(guī)范的SQL語句導(dǎo)致程序執(zhí)行效率低、甚至出錯無法正常運行。因此,在編寫SQL語句程序,切記不要胡亂的使用*。
(2)字段列表與源數(shù)據(jù)表排列順序雜亂、不規(guī)范。有些編程者在編寫SQL程序時很隨意,字段名、源數(shù)據(jù)表名任意排列、雜亂無序,程序在執(zhí)行時找不到合適的索引,導(dǎo)致查找速度慢,影響整個程序執(zhí)行效率。因此,在編寫SQL語句程序,字段名、源數(shù)據(jù)表名排列要遵循一定的規(guī)律(升序或降序),這樣程序在執(zhí)行時,才能夠按照規(guī)律找到合適的索引,提高查找效率,提升程序運行效果。
(3)INTO子句問題。select查詢的結(jié)果可以直接顯示,也可以不直接顯示。在程序設(shè)計過程當(dāng)中往往要用到查詢結(jié)果,但不直接顯示,有些編程者往往采用INTO語句將查詢結(jié)果保存到一個數(shù)據(jù)表中或一個臨時表中。在SQL Server數(shù)據(jù)庫系統(tǒng)中,如果要將查詢結(jié)果存放到臨時表,則在臨時表名前要加“#”號,如果當(dāng)用戶斷開連接時沒有除去臨時表,將自動除去臨時表。一旦被黑客捕捉到,會利用下列類似的程序代碼邏輯灌水,導(dǎo)致服務(wù)器資源耗盡而宕機:
procedure TForm1.Button1 Click(Sender:TObject);// Delphi程序主要代碼
var i:integer;
str,sqlstr:string;
begin
for i:=1 to 10000000000000000 do//可以執(zhí)行更多次,生成很多個表
begin
str:=inttostr(i);
form1.Query1. Close;
form1.Query1.SQL. Clear;
sqlstr:='test'+str;
form1.Query1.SQL.Text:='select*into'+sqlstr+' from目標(biāo)數(shù)據(jù)表';
form1.Query1.Prepare;form1.Query1.ExecSQL;
end;
end;
可以采用存儲過程、游標(biāo)等較為安全的方法來處理在程序中要用到查詢結(jié)果。
(4)SQL注入問題。用戶可以提交一段數(shù)據(jù)庫查詢代碼,根據(jù)程序返回的結(jié)果,獲得某些他想得知的數(shù)據(jù),這就是所謂的SQL Injection,即SQL注入。SQL注入的方法相當(dāng)靈活,往往根據(jù)具體情況進行分析,構(gòu)造巧妙的SQL語句,從而竊取想要的數(shù)據(jù)。例如下面的SQL語句:
SQL=”select u_right from tbl_user where ID=’’’+user_id+’’’+and PW=’’’+user_pw+’’’”
該語句通過用戶從系統(tǒng)界面輸入ID號user_id、PW密碼user_pw查詢用戶的權(quán)限,如果用戶正常并正確輸入自己的ID、PW,則該語句能夠按照程序設(shè)計的正常邏輯來運行。如果黑客輸入以下字符串:
ID處輸入:good(good可以用其它字符代替)。
PW處輸入:’OK’or’8’=’8’(OK可以用其它字符代替)。
則真正執(zhí)行的SQL語句如下所示:
selectu_righ t,user_id from tbl_userwhereID=’good’and PW=’OK’or’8’=’8’
where子句中的條件永遠為true,結(jié)果導(dǎo)致表tbl_user中所有用戶的信息都可以看到,用戶輸入攻擊字符串完成SQL注入。SQL語句強大的功能為SQL注入提供破壞力,精心構(gòu)造的攻擊字符能夠?qū)浖到y(tǒng)、數(shù)據(jù)庫進行非法操作、修改、植入等。
目前SQL注入的防范主要有手工檢查、自動過濾、SQL命令編碼以及專用的API等方法來防范。JAVA采用預(yù)編譯語句集,它內(nèi)置了處理SQL注入的能力,使用PreparedStatement來代替Statement來執(zhí)行SQL語句,SQL注入攻擊手段將無效。
有些程序在編寫SQL應(yīng)用程序時,只專注程序功能的實現(xiàn),沒有考慮程序的網(wǎng)絡(luò)安全、執(zhí)行效率等問題,導(dǎo)致應(yīng)用程序宕機、泄漏等問題。希望本文能夠使更多的程序員在編寫程序時提高程序的執(zhí)行效率和安全性。
[1]西爾伯沙茨.?dāng)?shù)據(jù)庫系統(tǒng)概念-(第五版影印版)[M].北京:高等教育出版社,2006.
[2]埃爾姆斯里,內(nèi)挖西.?dāng)?shù)據(jù)庫系統(tǒng)基礎(chǔ)-(第五版)[M].北京:人民郵電版社,2008.
Research andApplication of SQL Statements
Xu Hao
(Tianhe College of Guangdong Polytechnic Normal University,Guangzhou 510540,Guangdong)
This paper discusses the problems of SQL statements such as low efficiency and less-safety from the aspects of usage, specification,INTO clause and injection.It gives the corresponding strategies,and provides the useful experience for the follow-up study.
SQL;injection;security
徐昊,男,湖北鄂州人,碩士,高級工程師。研究方向:數(shù)據(jù)庫,算法等。