注入漏洞通常是指在可输入参数的地方,通过构造恶意代码,进而威胁应用安全和数据库安全。常见的注入漏洞包括:SQL注入和XSS跨站脚本攻击。 这篇文章我们主要讲SQL注入,SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
一,攻击案例
-
添加' or 1=1#获取全部数据
var userName= Request.Form["user_name"]; var passwd= Request.Form["password"]; var sql = "select * from user where username='"+userName+"' and password='"+passwd+"' ";
上面的变量user_name和password的值是由用户提交的,正常情况下,如果用户输入用户名admin和密码123456,那么sql语句是这样的。
select * from user where username='admin' and password='123456';
似乎看起来一切正常。
但是如果用户在用户名处输入'or 1=1#呢,那么实际的sql语句就变成这样了。select * from user where username='' or 1=1#' and password='123456';
因为#符号在sql中是注释符,所以sql server会忽略#后面的语句,因此上面的sql语句等价于:
select * from user where username='' or 1=1
因为1=1是个恒等条件,因此上面的sql语句便变成了下面的语句,查询出了全部用户。
select * from user
-
添加';drop table user#删除数据表
select * from user where username='';drop table user#' and password='123456';
因为#符号在sql中是注释符,因此上面的sql语句等价于:
select * from user where username='';drop table user
看出危险了吗,数据库会执行两条sql语句,第一条是一个带where条件的查询语句,第二条执行了drop table删除数据表的操作,最终会导致整个数据表被删除,如果数据库没有做好备份,会直接导致数据丢失,非常严重。
二,防范措施
通过前面两个案例我们可以看到,SQL注入发生的前提是应用程序直接相信和使用了用户的输入。那么我们有哪些防范措施呢。-
对用户输入进行转义
var userName= HtmlEncode(Request.Form["user_name"]); var passwd= HtmlEncode(Request.Form["password"]); var sql = "select * from user where username='"+userName+"' and password='"+passwd+"' ";
-
参数化查询
Private bool ProtectLogin(string userName, string password) { SqlParameter[] parameters = new SqlParameter[] { new SqlParameter{ParameterName="@UserName",SqlDbType=SqlDbType.NVarChar,Size=10,Value=userName}, new SqlParameter{ParameterName="@Password",SqlDbType=SqlDbType.VarChar,Size=20,Value=password} }; int count = (int)SqlHelper.Instance.ExecuteScalar ("SELECT COUNT(*) FROM Login WHERE UserName=@UserName AND Password=@password", parameters); return count > 0 ? true : false; }
-
限制web应用的数据库操作权限