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

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

1、工作量大

2、容易遗漏

3、不容易维护

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

一、sql注入的例子:

07e57ed99685e7934fd52151f0c7473f.gif

上面的输入有两个输入框,用户可以输入任何的值,包括有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 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(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 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;

}

}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值