NFine一个隐藏的漏洞(NFine基本上模仿力软的,力软应该也有,不知道新版本改了没),就是任何登录的用户都可以进行权限修改操作。
比如所有模块的SumbitForm或者其它弹出窗口上的按钮,本身只有登录权限验证,只要是登录用户就可以直接通过模拟Post,Get请求直接进行修改操作。
为了解决这个问题,本文实现一个权限管理办法,防止直接绕过验证,以ItemsData为例,下面上代码。
[HttpPost] [HandlerAjaxOnly] [HandlerAuthorize(true, @"/SystemManage/ItemsData/Form")] [ValidateAntiForgeryToken] public ActionResult SubmitForm(ItemsDetailEntity itemsDetailEntity, string keyValue) { itemsDetailApp.SubmitForm(itemsDetailEntity, keyValue); return Success("操作成功。");
注意HandlerAuthorize与原有的有什么不同,可能有人会问,为什么要使用/SystemManage/ItemsData/Form,因为这个模块的修改按钮权限就是这个,为了保持一致性。
public bool Ignore { get; set; } public string AuthorizeAction { get; set; } public HandlerAuthorizeAttribute(bool ignore = true,string authorizeAction="") { Ignore = ignore; AuthorizeAction = authorizeAction; }
原有的moduleId使用的cookie,根本就是防君子不防小人,而且影响判断,所以去掉。
private bool ActionAuthorize(ActionExecutingContext filterContext) { var operatorProvider = OperatorProvider.Provider.GetCurrent(); var roleId = operatorProvider.RoleId; var moduleId = ""; var action = HttpContext.Current.Request.ServerVariables["SCRIPT_NAME"].ToString(); if (!string.IsNullOrEmpty( AuthorizeAction))//指定需要某Action权限 { action = AuthorizeAction; } return new RoleAuthorizeApp().ActionValidate(roleId, moduleId, action); }
public bool ActionValidate(string roleId, string moduleId, string action) { .... else { authorizeurldata = cachedata; } //authorizeurldata = authorizeurldata.FindAll(t => t.F_Id.Equals(moduleId)); foreach (var item in authorizeurldata) { if (!string.IsNullOrEmpty(item.F_UrlAddress)) { string[] url = item.F_UrlAddress.Split('?'); //if (item.F_Id == moduleId && url[0] == action) if (url[0] == action) { return true; } } } return false;