SQL注入(一)
什么是SQL注入
可能大家还不是对SQL注入这个概念不是很清楚,简单地说,SQL注入就是攻击者通过正常的WEB页面,把自己SQL代码传入到应用程序中,从而通过执行非程序员预期的SQL代码,达到窃取数据或破坏的目的。
当应用程序使用输入内容来构造动态SQL语句以访问数据库时,会发生SQL注入攻击。如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字符串来传递,也会发生SQL注入。SQL注入可能导致攻击者使用应用程序登陆在数据库中执行命令。如果应用程序使用特权过高的帐户连接到数据库,这种问题会变得很严重。在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或者作为存储过程的输入参数,这些表单特别容易受到SQL注入的攻击。而许多网站程序在编写时,没有对用户输入的合法性进行判断或者程序中本身的变量处理不当,使应用程序存在安全隐患。这样,用户就可以提交一段数据库查询的代码,根据程序返回的结果,获得一些敏感的信息或者控制整个服务器,于是SQL注入就发生了。
一般SQL注入
在Web 应用程序的登录验证程序中,一般有用户名(username) 和密码(password) 两个参数,程序会通过用户所提交输入的用户名和密码来执行授权操作。我们有很多人喜欢将SQL语句拼接起来。例如:
Select * from users where username =’ txtusername.Text ’ and password =’ txtpassword.Text ’
其原理是通过查找users 表中的用户名(username) 和密码(password) 的结果来进行授权访问, 在txtusername.Text为mysql,txtpassword.Text为mary,那么SQL查询语句就为:
Select * from users where username =’ mysql ’ and password =’ mary ’
如果分别给txtusername.Text 和txtpassword.Text赋值’ or ‘1’ = ‘1’ --和abc。那么,SQL 脚本解释器中的上述语句就会变为:
Select * from users where username =’’or ‘1’ = ‘1’ -- and password =’abc’
该语句中进行了两个条件判断,只要一个条件成立,就会执行成功。而'1'='1'在逻辑判断上是恒成立的,后面的"--" 表示注释,即后面所有的语句为注释语句这样我们就成功登录。即SQL注入成功.
如果我们给txtusername.Text赋值为:’;drop table users--即:
Select * from users where username =’’;drop table users-- and password =’abc’
整个用户表就没有了,当然这里要猜出数据表名称。想想是多么可怕的事情。
好我想大家在这里已经大致明白了一般SQL注入了,试想下您的登录程序会不会出现我上述的情况。
防范SQL注入
那么现在大家都在思考怎么防范SQL注入了这里给出一点个人的建议
1.限制错误信息的输出
Select * from employee where userID=@userID;
如果用户输入: 09105022’OR ‘1’=’1,将得不到何记录,因为没有一个用户ID与文本框中输入的’ 09105022’OR ‘1’=’1’相等。参数化命令的语法随提供程序的不同略有差异。对于SQL SERVER提供程序,参数化命令使用命名的占位符(具有唯一的名字),而对于OLE DB提供程序,每个硬编码的值被问号代替。使用OLE DB提供程序时,需要保证参数的顺序和它们出现在SQL字符串中的位置一致。SQL SERVER提供程序没有这样的需求,因为它们用名字和占位符匹配。
4.调用存储过程
存储过程是存储在数据库服务器上的一系列SQL代码,存储过程与函数相似,有良好的逻辑封装结构,可以接收和返回数据。使用存储过程可以使代码更易于维护,因为对存储过程的更改不会导致应用程序的重新编译,使用存储过程还可以节省带宽,提高应用程序性能。因为存储过程是存储在数据库服务端的独立的封装体,调用存储过程可以保证应用程序只执行存储过程中的固定代码,从而杜绝SQL语句注入的可能。结合上述所讲的参数化命令,可以实现SQL代码可以实现的任何功能,并进一步提高应用程序的安全等级。
今天就写到这吧,后面还有一些防范的方法,可能更要实用一些,就在后面的文章介绍吧