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;