ASP.NET MVC 5使用Filter过滤Action参数防止sql注入

在开发程序的过程当中,稍微不注意就会隐含有sql注入的危险。今天我就来讲下,ASP.NET mvc 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁。不用每下地方对参数的值都进行检查,看是用户输入的内容是否有危险的sql。若是每一个地方都要加有几个缺点:sql

一、工做量大数据库

二、容易遗漏安全

三、不容易维护mvc

下面我经过写一个过滤防止sql的特性类,对Action执行前对Action的参数进行处理,若是有其值有sql语句,就会这些非法字符替换为空字符串。spa

1、sql注入的例子:

上面的输入有两个输入框,用户能够输入任何的值,包括有sql注入的值。code

后台代码:orm

AdminController.csblog

复制代码
public class AdminController : Controller
    {
        public ActionResult Index(string name = "", string loginName = "", int page = 1)
        {
            ViewBag.Name = name;
            ViewBag.LoginName = loginName;
            var r = DAdmin.GetList(name, loginName, page, 2);
            return View(r);
        }
    }
}
复制代码

DAdmin.cs:继承

复制代码
public class DAdmin
{
    public static PageDataView<MSys_Admin> GetList(string name, string loginName, int page,int pageSize=10)
    {
        PageCriteria criteria = new PageCriteria();
        criteria.Condition = "1=1";
        if (!string.IsNullOrEmpty(name))
            criteria.Condition += string.Format(" and Name like '%{0}%'", name);
        if (!string.IsNullOrEmpty(loginName))
            criteria.Condition += string.Format(" and LoginName like '%{0}%'", loginName);
        criteria.CurrentPage = page;
        criteria.Fields = "*";
        criteria.PageSize = pageSize;
        criteria.TableName = "Sys_Admin a";
        criteria.PrimaryKey = "UID";
        var r = Common.GetPageData<MSys_Admin>(criteria);
        return r;
    }
}
复制代码

上面对用户输入的name和loginName两个参数没有判断是否有sql注入的非法字符,就直接拼接到sql语句,到数据库中执行,这样是很是危险的。接口

一、好比用户在name输入这样的内容:

%'--%

这样拼接出来的sql语句就成了

SELECT * FROM Sys_Admin WHERE Name like '%'--%'

这样“--”是sql的注释标记后面再拼接的sql语句都当成注释了,这样有效的就成了这样的sql语句:

SELECT * FROM Sys_Admin WHERE Name like '%'

这表示显示所有的记录。若是是登陆的sql就会跳过用户名、密码的验证。 

二、若是用户name输入内容带有insert或delete或者drop,好比:

namer人值为:%';DELETE FROM Sys_Admin--%

拼接成的sql成了:

SELECT * FROM Sys_Admin WHERE Name like '%';DELETE FROM Sys_Admin--%'

这样一执行就把Sys_Admin表的记录所有删除了。

总结:上面能够看到这种sql注入是多么的危险。

2、解决MVC sql注入方案

一、定义一个防止sql注入的字符串辅助类

复制代码
{
    public static string FilterSql(string s)
    {
        if (string.IsNullOrEmpty(s)) return string.Empty;
        s = s.Trim().ToLower();
        s = ClearScript(s);
        s = s.Replace("=", "");
        s = s.Replace("'", "");
        s = s.Replace(";", "");
        s = s.Replace(" or ", "");
        s = s.Replace("select", "");
        s = s.Replace("update", "");
        s = s.Replace("insert", "");
        s = s.Replace("delete", "");
        s = s.Replace("declare", "");
        s = s.Replace("exec", "");
        s = s.Replace("drop", "");
        s = s.Replace("create", "");
        s = s.Replace("%", "");
        s = s.Replace("--", "");
        return s;
    }
}
复制代码

这个类对上面sql相关的字符串都替换掉。

二、定义一个用来检查并处理Action参数的特性类

复制代码
public class AntiSqlInjectAttribute:FilterAttribute,IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        
    }
 
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var actionParameters = filterContext.ActionDescriptor.GetParameters();
        foreach (var p in actionParameters)
        {
            if (p.ParameterType == typeof(string))
            {
                if (filterContext.ActionParameters[p.ParameterName] != null)
                {
                    filterContext.ActionParameters[p.ParameterName] = StringHelper.FilterSql(filterContext.ActionParameters[p.ParameterName].ToString());
                }
            }
        }
    }
}
复制代码

说明:这个特性类是继承了类FilterAttribute和实现了接口IActionFilter,这里在方法OnActionExecuting处理Action的参数,OnActionExecuting是在Action执行以前运行的方法,而OnActionExecuted是在Action执行以后运行的方法。

p.ParameterType == typeof(string)

由于sql注入只有参数类型为字符串的时候才有可能因此这里只对Action参数为字符串的参数进行处理。

filterContext.ActionParameters[p.ParameterName] = 
StringHelper.FilterSql(filterContext.ActionParameters[p.ParameterName].ToString());
是用过滤以后的安全的Action参数值替换原来的原始值。

三、防止sql注入特性类的在MVC的Controller中的使用

复制代码
public class AdminController : Controller
{
    [AntiSqlInject]
    public ActionResult Index(string name = "", string loginName = "", int page = 1)
    {
        ViewBag.Name = name;
        ViewBag.LoginName = loginName;
        var r = DAdmin.GetList(name, loginName, page, 2);
        return View(r);
    }
}
复制代码

须要对Action的参数进行sql检查,只用在前面加上,上面定义的特性类AntiSqlInject。这个特性类能够用在任何的须要防止sql注入的Action上,根本不用对手动的去过滤程序中获取到的全部参数,安全、方便简洁

相关文章
相关标签/搜索