1、工作量大
2、容易遗漏
3、不容易维护
下面我通过写一个过滤防止sql的特性类,对Action执行前对Action的参数进行处理,如果有其值有sql语句,就会这些非法字符替换为空字符串。
一、sql注入的例子:
上面的输入有两个输入框,用户可以输入任何的值,包括有sql注入的值。
后台代码:
AdminController.cs
DAdmin.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);
- }
- }
- }
- 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注入的字符串辅助类
这个类对上面sql相关的字符串都替换掉。
- public class StringHelper
- {
- 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;
- }
- }
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中的使用
需要对Action的参数进行sql检查,只用在前面加上,上面定义的特性类AntiSqlInject。这个特性类可以用在任何的需要防止sql注入的Action上,根本不用对手动的去过滤程序中获取到的所有参数,安全、方便简洁。
- 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);
- }
- }
.net网站&系统开发技术学习交流群:533829726
本站文章除注明转载外,均为本站原创或翻译,欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,共创和谐网络环境。
转载请注明:文章转载自:蓝狐软件工作室 » AOP实践--ASP.NET MVC 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁
本文标题:AOP实践--ASP.NET MVC 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁
本文地址:http://www.lanhusoft.com/Article/132.html
http://www.lanhusoft.com/Article/132.html