zoukankan      html  css  js  c++  java
  • ASP.NET MVC 5使用Filter过滤Action参数防止sql注入

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

    1、工作量大

    2、容易遗漏

    3、不容易维护

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

    一、sql注入的例子:

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

    后台代码:

    AdminController.cs

    复制代码
    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语句,到数据库中执行,这样是非常危险的。

    1、比如用户在name输入这样的内容:

    %'--%

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

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

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

    SELECT * FROM Sys_Admin WHERE Name like '%'

    这表示显示全部的记录。如果是登录的sql就会跳过用户名、密码的验证。 

    2、如果用户name输入内容带有insert或delete或者drop,比如:

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

    拼接成的sql成了:

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

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

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

    二、解决MVC sql注入方案

    1、定义一个防止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相关的字符串都替换掉。

    2、定义一个用来检查并处理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参数值替换原来的原始值。

    3、防止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上,根本不用对手动的去过滤程序中获取到的所有参数,安全、方便简洁

  • 相关阅读:
    Hdu 5396 Expression (区间Dp)
    Lightoj 1174
    codeforces 570 D. Tree Requests (dfs)
    codeforces 570 E. Pig and Palindromes (DP)
    Hdu 5385 The path
    Hdu 5384 Danganronpa (AC自动机模板)
    Hdu 5372 Segment Game (树状数组)
    Hdu 5379 Mahjong tree (dfs + 组合数)
    Hdu 5371 Hotaru's problem (manacher+枚举)
    Face The Right Way---hdu3276(开关问题)
  • 原文地址:https://www.cnblogs.com/wanzhongjun/p/10975302.html
Copyright © 2011-2022 走看看