在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
在开发程序的过程中,稍微不注意就会隐含有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] = 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上,根本不用对手动的去过滤程序中获取到的所有参数,安全、方便简洁 |
请发表评论