已经开始了学习牛腩新闻发布系统,在讲后台代码的时候讲了一些重构SQLHelper的知识,存储过程和触发器等,这些以前都是接触过的。而SQL注入是以前没有注意过的,所以停下来总结学习一下SQL注入。
首先什么是SQL注入呢?
实战篇~~~~~~~~~~
SQL注入概念
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令,比如先前的很多影视网站泄露VIP会员密码大多就是通过WEB表单递交查询字符暴出的,这类表单特别容易受到SQL注入式攻击。
通俗的说就是,当在浏览器网页中输入一些可能是查询字符串的一部分时,这样就使得恶意破坏人可以指导一个网站的连接数据库的名称和里面的表,这就是由于拼接字符串引起的。在新闻发布系统中的小例子:
新闻类别类插入函数的代码
public bool Insert(string caName) { bool flag = false; string sql = "insert into category(name) values('" + caName + "')";}; int res = sqlhelper.ExecuteNonQuery(sql, CommandType.Text); if (res > 0) //代码段,连续两次按table键显示代码段 { flag = true; } return flag; }
如果是这样的话:在网页输入框中输入类似
—— 娱乐新闻‘)delete category where id=3-- 的语句就会发生SQL注入。
这样的话,就会在插入娱乐新闻的时候同时删除id为3的那条类别。这就是SQL注入,造成了数据库的不安全,是因为正好拼接了字符串,insert
intocategory(name) values(‘娱乐新闻‘)delete
category whereid=3-
解决方法是使用参数,将sql语句该成为:
/// <summary> /// 增加类别 /// </summary> /// <param name="caName">新闻类别名称</param> /// <returns></returns> public bool Insert(string caName) { bool flag = false; string sql = "insert into category(name) values(@caName)"; SqlParameter[] paras = new SqlParameter[] { new SqlParameter ("@caName",caName )}; int res = sqlhelper.ExecuteNonQuery(sql, paras, CommandType.Text); //防止SQL注入 if (res > 0) //代码段,连续两次按table键显示代码段 { flag = true; } return flag; }
参数化查询为什么可以防止SQL注入?
1、参数过滤,数据库中实际执行的sql语句
2、执行计划重用
因为参数化查询可以重用执行计划,并且如果重用执行计划的话,SQL所要表达的语义就不会变化,所以就可以防止SQL注入,如果不能重用执行计划,就有可能出现SQL注入,存储过程也是一样的道理,,因为可以重用执行计划。
扩展篇~~~~~~~~~~
SQL注入原因
SQL注入的产生原因通常表现在以下几方面:
1、不当的类型处理
2、不安全的数据库配置
3、不合理的查询集处理
4、不当的错误处理
5、转义字符处理不合适
6、多个提交处理不当
SQL注入攻击指的是通过构建特殊的输入作为参数传入Web程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。
SQL注入的影响
当应用程序使用输入内容来构造动态sql语句以访问数据库时,会发生sql注入攻击。如果代码使用存储过程,而这些作为包含未筛选的用户输入的字符串来传递,也会发生sql注入。sql注入可能导致攻击者使用应用程序登陆在数据库中执行命令。相关的SQL注入可以通过测试工具pangolin进行。如果应用程序使用特权过高的帐户连接到数据库,这种问题会变得很严重。在某些表单中,用户输入的内容直接用来构造动态sql命令,或者作为存储过程的输入参数,这些表单特别容易受到sql注入的攻击。而许多网站程序在编写时,没有对用户输入的合法性进行判断或者程序中本身的变量处理不当,使应用程序存在安全隐患。这样,用户就可以提交一段数据库查询的代码,根据程序返回的结果,获得一些敏感的信息或者控制整个服务器,于是sql注入就发生了。
防护SQL注入
既然存在SQL注入的影响,那么怎样防止SQl注入呢?
1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和
双"-"进行转换等。
2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
总结篇~~~~~~~~~~
SQL注入,一听上去是多么专业的名词啊!可以如果要是有人故意因为这点漏洞就侵入数据库就不好了。同时也有各种各样的人在探寻SQL注入的方法,他们的手法相当灵活,让我们防不胜防。而我们的防护能不能根据具体情况进行分析,构造巧妙的SQL语句,从而成功防护了想要进行SQL注入的数据库才是高手与“菜鸟”的区别。