徐 昊
(广东技术师范学院天河学院,广东 广州 510540)
SQL语句的应用与研究
徐 昊
(广东技术师范学院天河学院,广东 广州 510540)
本文从SQL的用法、规范、INTO子句、注入(Injection)4个方面来探讨SQL语句在具体应用中出现的效率低、安全差等问题,并给出相应的策略,为后续进一步研究提供了有益的探索经验。
SQL;注入;安全
随着网络的广泛应用,基于B/S模式的应用程序也越来越多。由于程序员的水平及经验也参差不齐,一部分程序员在编写代码的时候,不注意书写规范、对用户输入数据的合法性不进行判断,使得应用程序执行效率低,且存在网络安全等问题。
查询是关系数据库中最基本的数据操作,通过SELE CT语句来实现,其基本语法格式[1]:
SELE CT[ALL|DISTIN CT]字段列表
[INTO目标数据表]
FROM源数据表[,…n]
[WHERE条件表达式]
[GROUP BY分组表达式]
[HAVING搜索表达式]
[ORDER BY排序表达式[,…n][AS C][DES C]]
[ CO MPUTE行聚合函数名(统计表达式)[,…n][BY分类表达式[,…n]]]
(1)*用法问题。对于初学者来说在编写SQL语句程序时,为了图方便,常用*来代替所有字段,经常会出现:Select *from…这样的语句。这种语句的功能是显示出表中的每一个字段的全部信息,包括不需要的信息也被显示出来,这样会消耗大量的内存开销、降低程序执行效率;如果表中含有图像、备注这样类型的字段,会导致程序出错无法正常运行。这种SQL写法虽然在逻辑上是没有问题,但往往在具体的实际应用中由于这种不规范的SQL语句导致程序执行效率低、甚至出错无法正常运行。因此,在编写SQL语句程序,切记不要胡乱的使用*。
(2)字段列表与源数据表排列顺序杂乱、不规范。有些编程者在编写SQL程序时很随意,字段名、源数据表名任意排列、杂乱无序,程序在执行时找不到合适的索引,导致查找速度慢,影响整个程序执行效率。因此,在编写SQL语句程序,字段名、源数据表名排列要遵循一定的规律(升序或降序),这样程序在执行时,才能够按照规律找到合适的索引,提高查找效率,提升程序运行效果。
(3)INTO子句问题。select查询的结果可以直接显示,也可以不直接显示。在程序设计过程当中往往要用到查询结果,但不直接显示,有些编程者往往采用INTO语句将查询结果保存到一个数据表中或一个临时表中。在SQL Server数据库系统中,如果要将查询结果存放到临时表,则在临时表名前要加“#”号,如果当用户断开连接时没有除去临时表,将自动除去临时表。一旦被黑客捕捉到,会利用下列类似的程序代码逻辑灌水,导致服务器资源耗尽而宕机:
procedure TForm1.Button1 Click(Sender:TObject);// Delphi程序主要代码
var i:integer;
str,sqlstr:string;
begin
for i:=1 to 10000000000000000 do//可以执行更多次,生成很多个表
begin
str:=inttostr(i);
form1.Query1. Close;
form1.Query1.SQL. Clear;
sqlstr:='test'+str;
form1.Query1.SQL.Text:='select*into'+sqlstr+' from目标数据表';
form1.Query1.Prepare;form1.Query1.ExecSQL;
end;
end;
可以采用存储过程、游标等较为安全的方法来处理在程序中要用到查询结果。
(4)SQL注入问题。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。SQL注入的方法相当灵活,往往根据具体情况进行分析,构造巧妙的SQL语句,从而窃取想要的数据。例如下面的SQL语句:
SQL=”select u_right from tbl_user where ID=’’’+user_id+’’’+and PW=’’’+user_pw+’’’”
该语句通过用户从系统界面输入ID号user_id、PW密码user_pw查询用户的权限,如果用户正常并正确输入自己的ID、PW,则该语句能够按照程序设计的正常逻辑来运行。如果黑客输入以下字符串:
ID处输入:good(good可以用其它字符代替)。
PW处输入:’OK’or’8’=’8’(OK可以用其它字符代替)。
则真正执行的SQL语句如下所示:
selectu_righ t,user_id from tbl_userwhereID=’good’and PW=’OK’or’8’=’8’
where子句中的条件永远为true,结果导致表tbl_user中所有用户的信息都可以看到,用户输入攻击字符串完成SQL注入。SQL语句强大的功能为SQL注入提供破坏力,精心构造的攻击字符能够对软件系统、数据库进行非法操作、修改、植入等。
目前SQL注入的防范主要有手工检查、自动过滤、SQL命令编码以及专用的API等方法来防范。JAVA采用预编译语句集,它内置了处理SQL注入的能力,使用PreparedStatement来代替Statement来执行SQL语句,SQL注入攻击手段将无效。
有些程序在编写SQL应用程序时,只专注程序功能的实现,没有考虑程序的网络安全、执行效率等问题,导致应用程序宕机、泄漏等问题。希望本文能够使更多的程序员在编写程序时提高程序的执行效率和安全性。
[1]西尔伯沙茨.数据库系统概念-(第五版影印版)[M].北京:高等教育出版社,2006.
[2]埃尔姆斯里,内挖西.数据库系统基础-(第五版)[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
徐昊,男,湖北鄂州人,硕士,高级工程师。研究方向:数据库,算法等。