是什么?
我们知道大部分网站对用户交互使用的过程都是存储在数据库当中,网站的每个功能都会获取用户主动或被动输入的关键数据,而网站的后端已经封装好了一个完整的sql语句,只需要将用户输入的关键数据放入sql语句的固定查询点内,sql查询之后就会返回给用户一个想要的内容,并通过用户用的浏览器,在前端显示,变成一个交互的网页。
在这个过程中,如果用户输入的数据是一个sql语言片段,当这个片段传入后端,放入固定的sql语句查询点后,会破坏sql语句原有的查询方法,当用户输入的sql语言片段是恶意的,完全可以达到使原有的sql语句功能失效,而实际执行内容被控制的结果,恶意用户就可以不断的变化输入sql片段,从数据库中返回不应该被查询到的数据,返回到浏览器的前端。
这样的一个通过sql语句片段,恶意访问或破坏数据库的行为,就是sql注入。
分类
根据漏洞点本身接受数据类型,我们把sql注入分为两类。
第一种使数字型注入
漏洞点原有功能是从用户端获取一个数字,然后到数据库中查询数字对应的信息,我们可以简单的认为是这样的:select * from news where ID=1;1作为用户段输入的内容,在这种情况下,1后面可以直接输入sql片段,然后破坏进行执行(增删改查都可以)。
另一种是字符型注入
在查询语句中用户输入被当做字符串处理的情况,查询语句可能为:select * from Users where name=‘test’;test为用户端输入的内容,在这种情况下,恶意用户可以将test两端的单引号进行闭合处理,使之破坏后还是一个合法的sql语句,比如用户可以输入这样的内容:test’ or ‘1’='1,这样即处理了单引号的问题,又是一个可以被控制的sql语句。
防御
1、用户端输入判断是否合法,值接受合法的输入;
比如我们做的学生信息管理系统和机房收费系统中,对客户端输入数据的合法性进行的判断。
2、后端用语义分析等waf分析;
3、使用存储过程来防御(安全性不是很高)
举个例子
我们在敲新闻发布系统的时候,有这样的一个功能,管理员可以添加新闻类别:
public bool Insert(string caName)
{
bool flag = false;
//被封装好的sql语句,用户只需要添加caName关键字即可
string sql = "insert into category(name) values ('" + caName + "')";
int res = sqlhelper.ExecuteNonQuery(sql);//传入sqlhelper层被执行
if (res > 0)
{
flag = true;
}
return flag;
}
如果用户输入的内容是这样的:娱乐新闻’) delete category – 这样的话,数据库中的整个表都被删除了,后果不堪设想。
我们可以对上面的代码进行优化:我们在插入的时候不能够直接使用构造的sql语句,我们可以使用带参数的sql语句。
原来的:
string sql = "insert into category(name) values ('" + caName + "')";
现在可以改成:
string sql = "insert into category(name) values (@caName)";
//通过SqlParameter参数给@caName赋值
SqlParameter[] paras = new SqlParameter[]
{
new SqlParameter ("@caName",caName )
};
这样以来,我们直接在方法中传入一个caName参数就可以了,数据库中会自动将@caName当成一个字符串来处理
明白了sql注入的原理,对于它的防止就不成问题了,但前提是我们还需要不断的学习,探索更多的知识。
感谢阅读,喜欢的话点个赞吧!