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

原文地址:https://www.cnblogs.com/wanzhongjun/p/10975302.html

时间: 2024-10-12 16:29:00

ASP.NET MVC 5使用Filter过滤Action参数防止sql注入的相关文章

ASP.NET MVC 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁

在开发程序的过程中,稍微不注意就会隐含有sql注入的危险.今天我就来说下,ASP.NET mvc 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁.不用每下地方对参数的值都进行检查,看是用户输入的内容是否有危险的sql.如果每个地方都要加有几个缺点: 1.工作量大 2.容易遗漏 3.不容易维护 下面我通过写一个过滤防止sql的特性类,对Action执行前对Action的参数进行处理,如果有其值有sql语句,就会这些非法字符替换为空字符串. 一.sql注入的例子: 上面的输入

走入asp.net mvc不归路:[4]说说Action有哪些常见成员

一个控制器中,功能最终会落实到一个个Action中实现,最常见的是增删查改操作.这些Action是一个个的方法,一般返回值是ActionResult,并且是public 方法,可以带参数,可以添加元标记,可以结合linq直接访问数据库,可以结合Model进行合法性验证等等,还是比较灵活的.增就是添加记录,如添加一个域名,一个产品:删,就是删除一条记录:查,包含列表显示及单个记录的显示:改就是指的修改记录. 1 最常见的Action当属增删查改功能 2 其中Index是列表,在示例中即列出所有的域

通过源码了解ASP.NET MVC 几种Filter的执行过程

一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多人觉得平时根本不需要知道这些,会用就行了.其实阅读源码是个很好的习惯,它不只停留在知道怎么用的阶段,而是让我们知道一系列的为什么,为什么这样设计,为什么这样使用....很多朋友应该看过<asp.net x 框架揭秘>这本书,确实不错,特别是边看源码边看书,可以有不小的收获.Ok,我不是大神,我只是心血来潮想看一下源码! 二.几种常见的Filter

Attribute(二)——自定义特性+Asp.net MVC中的filter详解

上篇博客是关于特性中有关预定义特性的一些基础,同时也是对Attribute这一概念的一个宏观上的认识,在上篇博客结尾介绍了有关为自定义特性服务的AttributeUsage,这篇博客主要是通过filter的使用间接的了解自定义特性的具体应用. 一.filter简介 在了解自定义特性前,先引入一个概念filter,它是MVC中自带的一种功能,在我们项目中通常会遇到在Action执行前或结束时,去执行日志记录或错误处理等功能,通常可使用AOP截取来实现,但是在MVC中提供了filter过滤,大大方便

ASP.NET MVC中的两个Action之间值的传递--TempData

一. ASP.NET MVC中的TempData 在ASP.NET MVC框架的ControllerBase中存在一个叫做TempData的Property,它的类型为TempDataDictionary,顾名思义是一个字典类.TempData在ASP.NET MVC中的作用是:可用于在Action执行过程之间传值.简单的说,你可以在执行某个Action的时候,将数据存放在TempData中,那么在下一次Action执行过程中可以使用TempData中的数据. 如: 1 public Actio

ASP.NET mvc下在Controller下action的跳转方式

在ASP.NET mvc下,action有多种挑战方式: return RedirectToAction("Index");//一个参数时在本Controller下 如果RedirectToAction(ActionName,ControllerName) //可以直接跳到别的Controller. return RedirectToRoute(new {controller="Home",action="Index"});//可跳到其他cont

ASP.NET MVC 动态修改form的action值

在练习ASP.NET MVC时,为了实现一个小功能,POST数据至服务器执行时,需要动态修改form的action值. 下面Insus.NET列举一个例子来演示它.让它简单,明白易了解. 你可以在控制器中,创建3个操作action: 标记1是实现视图,而标记2与3是为form的action.其中Isus.NET有使用ContentResult来替代Response.Write向视图输出结果. 在视图中,我们在form中,放一个文件框,两个铵钮,但没有在form中,设置action值.稍后我们在铵

[ASP.NET MVC 小牛之路]05 - 使用 Ninject实现依赖注入

在[ASP.NET MVC 小牛之路]系列上一篇文章(依赖注入(DI)和Ninject)的末尾提到了在ASP.NET MVC中使用Ninject要做的两件事情,续这篇文章之后,本文将用一个实际的示例来演示Ninject在ASP.NET MVC中的应用. 为了更好的理解和撑握本文内容,强烈建议初学者阅读本文前先阅读依赖注入(DI)和Ninject. 本文目录: 准备工作 新建一个名为BookShop的空白解决方案.在该解决方案中分别添加一个名为BookShop.WebUI的MVC空应用程序,和一个

ASP.NET MVC什么时候使用异步Action

在没有使用异步Action之前,在Action内,比如有如下的写法: public ActionResult Index() { CustomerHelper cHelper = new CustomerHelper(); List<Customer> result = cHelper.GetCustomerData(); return View(result); } 以上,假设,GetCustomerData方法是调用第三方的服务,整个过程都是同步的,大致是: →请求来到Index这个Act