技术开发 频道

SQL Injection:网络攻击及其防范措施

  参数化SQL语句

  还是回到之前动态拼接SQL基础上,我们知道一旦有恶意SQL代码传递过来,而且被拼接到SQL语句中就会被数据库执行,那么我们是否可以在拼接之前进行判断呢?——命名SQL参数。

string sql1 = string.Format("SELECT job_id, job_desc, min_lvl, max_lvl FROM jobs WHERE job_id = @jobId");
using (
var con = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLCONN1"].ToString()))
using (
var com = new SqlCommand(sql1, con))
{
    
// Pass jobId to sql statement.
    com.Parameters.
Add("@jobId", SqlDbType.Int).Value = jobId;
    com.Connection.
Open();
    gdvData.DataSource
= com.ExecuteReader();
    gdvData.DataBind();
}

  

SQL Injection防范措施(2)
▲图8 参数化SQL查询结果

  这样我们就可以避免每个数据库操作(尤其一些简单数据库操作)都编写存储过程了,而且当用户具有数据库中jobs表的读权限才可以执行该SQL语句。

  添加新架构

  数据库架构是一个独立于数据库用户的非重复命名空间,您可以将架构视为对象的容器(类似于.NET中的命名空间)。

  首先我们右击架构文件夹,然后新建架构。

SQL Injection防范措施(2)

SQL Injection防范措施(2)
▲图9 添加HumanResource架构

  上面我们完成了在pubs数据库中添加HumanResource架构,接着把jobs表放到HumanResource架构中。

SQL Injection防范措施(2)

SQL Injection防范措施(2)
▲图 10 修改jobs表所属的架构

  当我们再次执行以下SQL语句时,SQL Server提示jobs无效,这是究竟什么原因呢?之前还运行的好好的。

SELECT job_id, job_desc, min_lvl, max_lvl FROM jobs

  

SQL Injection防范措施(2)
▲图 11 查询输出

  当我们输入完整的表名“架构名.对象名”(HumanResource.jobs)时,SQL语句执行成功。

SELECT job_id, job_desc, min_lvl, max_lvl FROM HumanResource.jobs

  

SQL Injection防范措施(2)

        为什么之前我们执行SQL语句时不用输入完整表名dbo.jobs也可以执行呢?

  这是因为默认的架构(default schema)是dbo,当只输入表名时,Sql Server会自动加上当前登录用户的默认的架构(default schema)——dbo。

  由于我们使用自定义架构,这也降低了数据库表名被猜测出来的可能性。

  LINQ to SQL

  前面使用了存储过程和参数化查询,这两种方法都是非常常用的,而针对于.NET Framework的ORM框架也有很多,如:NHibernate,Castle和Entity Framework,这里我们使用比较简单LINQ to SQL。

SQL Injection防范措施(2)
▲图 12 添加jobs.dbml文件

var dc = new pubsDataContext();
int result;

// Validates jobId is int or not.
if (int.TryParse(jobId, out result))
{
    gdvData.DataSource
= dc.jobs.Where(p => p.job_id == result);
    gdvData.DataBind();
}

  相比存储过程和参数化查询,LINQ to SQL我们只需添加jobs.dbml,然后使用LINQ对表进行查询就OK了。

  总结

  我们在本文中介绍了SQL Injection的基本原理,通过介绍什么是SQL Injection,怎样进行SQL Injection和如何防范SQL Injection。通过一些程序源码对SQL的攻击进行了细致的分析,使我们对SQL Injection机理有了一个深入的认识,作为一名Web应用开发人员,一定不要盲目相信用户的输入,而要对用户输入的数据进行严格的校验处理,否则的话,SQL Injection将会不期而至。

  最后,祝大家新年快乐,身体健康,Code with pleasure。

  参考

  http://en.wikipedia.org/wiki/SQL_injection

  http://msdn.microsoft.com/zh-cn/library/bb153640%28v=SQL.90%29.aspx

0
相关文章