ado.net访问数据库流程2-防注入攻击
SQL注入攻击就是指在我们进行登录访问数据库时,由于用户登录时输入的登录名和密码等字段数据的合法性未作判断,同时利用访问时执行SQL command 语句
什么是SQL注入攻击(SQL injection)? SQL注入攻击就是指在我们进行登录访问数据库时,由于用户登录时输入的登录名和密码等字段数据的合法性未作判断,同时利用访问时执行SQL command 语句时,数据库不会对字段的合法性做二次判断的漏洞,运用巧妙的数据库连接或判断语句,使其省去用户名和密码的验证,实现无账号密码登录程序或者网站,盗取数据库信息等行为。 简单来说就是 恶意填入查询代码,致使SQL把被篡改的原本SQL字符串当做合法参数进行查询,达到免账密登录的目的。 常见的注入攻击手段(SQL injection methods)? SQL代码恶意注入攻击法:即利用恶意填补验证代码,使数据库在执行完你填补的代码后省去对真正验证代码的执行。 如这种代码: userId= ‘‘1’or ‘1’=‘1’--’; passWord = ‘‘1’or ‘1’=‘1’’; SQL Server 在执行时,其原SQL字符串 string sql=string.Format("select * from TestSchool where ( userId = ' '' + uid +'' ' )and (passWord =' '' + pwd +'' ')"); 就会变成: string sql=string.Format("select * from TestSchool where (userId = '1' or '1'='1' --) and (passWord = '1' or '1'='1')"); 那么无疑SQL字符串就被简化成了: string sql = "select * from TestSchool "; 这样就避过了用户名和密码的验证过程,直接就读取到了数据库的所有内容,实现免密登录了。 备注:易被攻击的访问连接请参见ADO.NET访问流程详解 怎么防止SQL注入攻击呢? SQL注入攻击是数据库安全以前常见的问题,容易导致刷库、拖库、撞库等风险,现在安防技术有:数据库漏扫、数据库加密、数据库防火墙、数据脱敏、数据库安全审计系统等成熟的技术。 如果使我们在编写的时候就把这种简单的恶意代码合法检验剔除掉,数据库就相对安全多了。下面针对讲一下,如何避免恶意代码注入攻击的预防方法:参数化查 什么是参数化查询(Parameterized Query)? 简单的来说就是设计数据库访问连接时,在Textbox等要填入数据或值的地方,先将值转换成参数,然后再使用参数来进行传值操作。这种方法是目前在设计时最有效的预防注入攻击的方法。 参数化查询方法(借用SqlParameter类对象)? --@参数占位符 string sql = string.Format('select * from TestSchool where userId = @uid and PassWord = @pwd '); SqlParameter p = new SqlParameter("@uid",txtuid.Text.Trim()); SqlParameter p1 = new SqlParameter("@pwd",txtpwd.Text.Trim()); SqlCommand cmd = new SqlCommand( sql,conn); cmd.Parameters.Add(p); cmd.Parameters.Add(p1); sql中定义局部变量(@) ? 定义变量uid 可变字符串字段mssql拖库,长度为50. declare @uid nvarchar(50); 可以发现 定义变量 需要用到@作为变量前缀。 因此在 userId = @uid 相当于 userId = 变量(@+变量名) 然后通过 SqlParameter p = new SqlParameter ("@uid",txtuid.Text.Trim()); 创建参数p ,通过变量uid ,将txtuid.Text.Trim()中输入的数据保存到参数p中。 参数化查询三步曲: 第一步: sql中创建用于接受输入框数据的变量。 string sql = string.Format('select * from TestSchool where userId = @uid and PassWord = @pwd '); 第二步: C#中创建输入框对应的参数,包括参数对象、参数名称。 SqlParameter p = new SqlParameter("@uid",txtuid.Text.Trim()); SqlParameter p1 = new SqlParameter("@pwd",txtpwd.Text.Trim()); 第三步: 实现Client和Sql服务器之间的交互,即将C#输入框值通过参数p传递给服务器,去执行相应的sql命令(string sql语句)。 SqlCommand cmd = new SqlCommand( sql,conn); cmd.Parameters.Add(p); cmd.Parameters.Add(p1); 通过这三步,可以很容易的将拼接字符串的致命缺点:注入攻击进行抵挡。 参数化查询预防注入攻击的实质 参数化实现注入攻击防御实质在于添加转义,给sql语句一转义封装。 当我们在uid登录输入框中输入: ‘ or '1' ='1' -- 是 原则上是会判断 or '1'='1' --注释掉后面的密码判断过程。即执行语句: select * from TestSchool where userId = ' ''+ or '1'='1' -- +'' ' and passWord = ' '' + pwd + '' ' ; --在sql中表示注释, 原句 -- +'' ' and passWord = ' '' + pwd + '' ' ; 会被忽略, --变成执行该语句: select * from TestSchool where userId = ' ''+ or '1'='1' 但是 当我们用参数化查询进行设计时,我们的输入框内容: ' or ‘1’=‘1’-- ; --txtuid.Text.Trim() ' ado or ‘1’=‘1’ ; --txtpwd.Text.Trim() 会经过一次封装过程变成执行这样的语句[在SQL Server Profiler中可查]: exec sp_executesql N' select * from TestSchool where userId = @uid and PassWord = @pwd ' , N' @uid nvarchar(50), @pwd nvarchar(10)', @uid = N' '' or '1'='1' -- ', @pwd = N' '' ado or ‘1’=‘1' ' 这里我们明显就看到 整个@uid 变量 被用 N'' 封装了一次,此时的 ' or '1'='1' -- 的第一个单引号变成了双引号,也就致使他成了一个单纯的字符串值[ ' or '1'='1' -- ]。因此,躲过了sql拼接字符串注入攻击。 第二种参数化查询方式: 用Parameters.AddWithValue();方法 具体如下: using (SqlCommand cmd=conn.CreateCommand()) { cmd.CommandText = "select * from TestSchool where userId = @uid and PassWord = @pwd "; cmd.Parameters.AddWithValue("@uid", ' or ‘1’=‘1’-- ); cmd.Parameters.AddWithValue("@pwd", ' ado or ‘1’=‘1'); } 注意: 1.创建 执行命令实例 SqlCommand cmd=conn.CreateCommand() 2.连接字符串连接方式 cmd.CommandText = "sql 执行语句 "; 3..AddWithValue()方法的使用 cmd.Parameters.AddWithValue("@uid", txtuid.Text.Trim() ); (编辑:海南站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |