一种基于ASP.NET的SQL注入漏洞防范措施

2018-12-25 12:07孟庆君杜瑞庆
科技资讯 2018年18期

孟庆君 杜瑞庆

摘 要:现今网站上的数据库大多使用SQL Server数据库,对数据库进入访问时一般需要输入账户和密码进行登录,但是SQL存在的注入漏洞可以使任意账户顺利登录,文章探讨了常见的SQL注入万能密码能够成功登录的原因,并提出了使用参数化查询解决这种问题的方法。参数化查询首先编译SQL语句,仅将参数进行编译,其后紧随的恒为真的条件语句将被截取掉,因此实现对注入漏洞的防范。

关键词:ASP.NET SQL注入漏洞 登录 参数化查询

中图分类号:TP393 文献标识码:A 文章编号:1672-3791(2018)06(c)-0007-02

在网络日益盛行的今天,通过网络可以进行各种各样的操作,包括生活中的各种与财务相关操作,比如:转账操作以及手机话费、水电费、煤气费与暖气费的缴纳。在进行财务操作之前,需要进行用户登录操作,即要求用户首先输入账号和密码,在服务器上验证通过才可进行后面的操作。通过账号与密码的验证可保障用户信息的安全,尤其是财务信息安全。

1 SQL注入漏洞

这些账号和密码大都保存在服务器上的数据库文件中,大部分网站使用的数据库是微软出品的SQL Server数据库。这种数据库功能强大,使用方便,但在安全性上也有一定的漏洞。比如:常见的SQL注入漏洞,它使得用户可能通过输入一些特殊的密码就能够以假乱真,正常登录,并进行登录后的财务操作,从而造成用户的账务损失。表1列出了一些常见的SQL注入万能密码。

网站上的用户登录网页往往以图1形式存在,要求用戶在文本框中输入用户名和密码,然后点击“登录”按钮进行验证。许多这样的网页是由ASP.NET(C#)开发的,点击“登录”按钮时,会将文本框中的用户名与密码取出来与SQL Server数据库中的已经存储的用户信息进行比对,成功则进入下一步操作;如果数据库中没有相应用户信息,或者有用户的账号,但密码不正确,都不能通过验证,也不能进入下一步的操作。但SQL Server的注入漏洞,使一些万能密码可以骗过网页的验证程序。原因如下。

首先要分析一下用户登录页面的代码,就能找到原因。点击“登录”按钮的关键代码如下。

string strUserName = txtUser.Text;

string strUserPwd = txtPwd.Text;

……

com.CommandText = "select * from userInfo where userName='"+strUserName+"'and userPwd='"+strUserPwd+"'";

从代码中可以看到,首先获取文本框中的账号和密码,然后用查询语句来验证用户名与密码是否都正确。如果输入的用户名为“user123”,密码为“123123”,则查询语句会变为“select * from userInfo where userName='user123' and userPwd='123123' ”,这时从数据库中如果能够查找到账号与密码都正确的信息才能够通过登录验证,如果其中有一个不正确,则不能通过验证。SQL注入万能密码利用了这个查询语句中的逻辑表达式的漏洞,给它加上一个绝对为真的条件,达到以假乱真、输入任意账户名均可登录的目的。那么,它是如何做到的?

例如:在网页显示的账号文本框中随便输入一个用户名“aaa”,再在密码文本框中输入一个万能密码“' or 'a'='a”,则查询语句会变为“select * from userInfo where userName='aaa' and userPwd='' or 'a'='a'”。可以看到其中的逻辑表达式中有一个“'a'='a'”恒为真的条件,因此不管用户名“aaa”在数据库中是否存在,其对应的密码是否存在,这个查询语句中的逻辑表达式恒为真,查询就相当于“select * from userInfo where 1”,因此可以登录成功。

2 SQL注入漏洞的预防

以前对付这种漏洞的方式主要有3种。

(1)字符串检测。限定输入的内容只能由英文、数字等常规字符,如果检查到用户输入有特殊字符,直接拒绝。缺点是,系统中不可避免地会有些内容包含特殊字符,这时候总不能拒绝入库。

(2)字符串替换。把危险字符替换成其他字符,缺点是危险字符可能有很多,一一枚举替换相当麻烦,也可能有漏网之鱼。

(3)存储过程。把参数传到存储过程进行处理,但并不是所有数据库都支持存储过程。如果存储过程中执行的命令也是通过拼接字符串出来的,还是会有漏洞。

近年来,自从参数化查询出现后,SQL注入漏洞基本杜绝。

3 参数化查询

参数化查询(Parameterized Query 或 Parameterized Statement)是访问数据库时,在需要填入数值或数据的地方,使用参数(Parameter)来给值。在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有指令,也不会被数据库运行。Access、SQL Server、MySQL、SQLite等常用数据库都支持参数化查询。

ASP.NET(C#)创建的网页中,也可利用参数化查询的方法对注入漏洞进行防范。将上述的代码加上参数化查询的语句即可,如下所示:

com.CommandText = "select * from userInfo where userName=@user and userPwd=@pwd”;

com.Parameters.Add("@user",System.Data.SqlDbType.VarChar,20).Value=txtUser.Text.Trim();

com.Parameters.Add("@pwd",System.Data.SqlDbType.VarChar,20).Value=txtPwd.Text.Trim();

从代码中可以看到为sqlCommand对象com增加了两个参数,分别命名为“@user”与“@pwd”,并将账户号与密码作为参数值传给这两个参数,在进行数据库查询时,数据库首先要将查询语句进行编译。在编译时,仅常量参与编译,因此就无法追加恒为真的后门命令。上面谈到的例子中,查询语句“select * from userInfo where userName='aaa' and userPwd='' or 'a'='a'”在编译时会截取为“select * from userInfo where userName='aaa' and userPwd=''”,后面恒为真的条件就不存在了,因此就防范了注入漏洞。

4 结语

参数化查询是防范SQL注入漏洞的一种方法,它首先编译SQL语句,仅将参数进行编译,其后紧随的恒为真的条件语句将被截取掉,因此实现对注入漏洞的防范。

参考文献

[1] 张莹莹,凌捷.一种SQL注入漏洞定位检测方法[J].计算机应用与软件,2016,33(2):314-317.

[2] 练坤梅,许静,田伟,等.SQL注入漏洞多等级检测方法研究[J].计算机科學与探索,2011,5(5):474-480.

[3] 马小婷,胡国平,李舟军.SQL注入漏洞检测与防御技术研究[J].计算机安全,2010(11):18-24.

[4] 彭赓,范明钰.基于改进网络爬虫技术的SQL注入漏洞检测[J].计算机应用研究,2010,27(7):2605-2607.

[5] 朱辉,沈明星,李善平.Web应用中代码注入漏洞的测试方法[J].计算机工程,2010,36(10):173-175,178.

[6] 张涛,王行建.对SQL注入漏洞的研究与防范措施的探讨[J].计算机时代,2006(11):30-31,38.

[7] 顾坤鹏,宋顺林.基于C++的关系代数产生的安全SQL查询[J].计算机与现代化,2011(10):177-180.