0

我正在努力解决一些应用程序漏洞。我有一个带有 urlhttp://localhost:12997/Manning_HQ/Edit/1274的编辑页面,问题是用户能够更改 id 并能够访问不应该访问的其他请求。

我搜索了,URLEncoding但发现它只能确保所有浏览器都能正确传输 URL 字符串中的文本。我的问题是有办法防止这种情况吗?

我的编辑功能:

// GET: Manning_HQ/Edit/5
        [CustomAuthorize(Roles = AccessRoleHelper.Add_Manning_Plan_HQ)]
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var test1 = (from c in db.TBL_Manning_HQ
                         join e in db.TBL_User_Dep_Access
                         on c.Inserted_By equals e.UserID
                         join t in db.TBL_Department
                         on c.Department_ID equals t.Department_ID
                         join p in db.TBL_Location
                         on c.Location_ID equals p.Location_ID
                         join n in db.TBL_Titles_HQ
                        on c.TitleHQ_ID equals n.TitleHQ_ID

                         where (e.Dep_ID == c.Department_ID)
                         where c.Manning_HQ_ID == id
                         select new Manning_HQ_VM
                         {
                             Manning_HQ_ID = c.Manning_HQ_ID,

                         }).ToList();
          
            TBL_Manning_HQ tBL_Manning_HQ = db.TBL_Manning_HQ.Find(id);
            int userid = Convert.ToInt32(Request.ServerVariables["LOGON_USER"].ToString().Split('\\')[1].ToString().Remove(0, 2));

            if (tBL_Manning_HQ == null)
            {
                return HttpNotFound();
            }
            var departments = (from d in db.TBL_Department
                               join ud in db.TBL_User_Dep_Access
                               on d.Department_ID equals ud.Dep_ID
                               join m in db.TBL_Manning_HQ
                               on d.Department_ID equals m.Department_ID
                               where ud.UserID == userid && ud.IsActive == true
                               where m.Manning_HQ_ID == id
                               select new KeyValuePairsViewModel
                               {
                                   Id = d.Department_ID,
                                   Value = d.Department_Name
                               }).ToList();

            ViewBag.Department_ID = new SelectList(departments, "Id", "Value");
            ViewBag.Location_ID = new SelectList(db.TBL_Location, "Location_ID", "Location_Name", tBL_Manning_HQ.Location_ID);
            ViewBag.TitleHQ_ID = new SelectList(db.TBL_Titles_HQ, "TitleHQ_ID", "Title_Name", tBL_Manning_HQ.TitleHQ_ID);


            if (test1.Count != 0)
            {

                return View(tBL_Manning_HQ);

            }
            else
            {
                return View();

            }
        }


        [HttpPost]
        [CustomAuthorize(Roles = AccessRoleHelper.Add_Manning_Plan_HQ)]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(TBL_Manning_HQ _HQ)
        {
            
            var chk_ID = db.TBL_Manning_HQ.Any(x => x.Manning_HQ_ID == _HQ.Manning_HQ_ID);
            var Chk_Dep = db.TBL_Manning_HQ.Where(x=>x.Manning_HQ_ID == _HQ.Manning_HQ_ID).Any(x => x.Department_ID == _HQ.Department_ID);

            if (chk_ID && Chk_Dep)
            {
                _HQ.Update_By = Convert.ToInt32(Request.ServerVariables["LOGON_USER"].ToString().Split('\\')[1].ToString().Remove(0, 2));
                _HQ.Update_In = DateTime.Now;

                db.SaveChanges();

                TempData["success"] = "Data updated successfully !";
            }

            return RedirectToAction("Index");
        }

自定义授权:

 public class CustomAuthorize : AuthorizeAttribute
    {
        Staff_RequisitionEntities_1 db = new Staff_RequisitionEntities_1();

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }

            if (filterContext.HttpContext.User == null)
            {
                throw new ArgumentNullException("filterContext.HttpContext.User");
            }

            string username = filterContext.HttpContext.User.Identity.Name.ClientName();
            int xceedId = Convert.ToInt32(username.Substring(2));
           
            var user = db.TBL_UserPermissions.FirstOrDefault(us => us.UserID== xceedId && us.IsActive == true);

            {
                filterContext.HttpContext.User = new CustomPrincipal((WindowsIdentity)filterContext.HttpContext.User.Identity,user, true , Convert.ToString(xceedId));
                base.OnAuthorization(filterContext);

            }
        }
    }

访问角色助手:

 public class AccessRoleHelper
    {
        public const string Manning_Plan = "Add Manning Plan";    
        public const string View_Manning_Plan = "View Manning Plan";    
        public const string Add_New_Request = "Add New Request";    
        public const string View_Requestes = "View Requestes";    
        public const string Add_Fulfillment_Rate = "Add Fulfillment Rate";    
        public const string View_Fulfillment_Rate = "View Fulfillment Rate";
        public const string Add_Manning_Plan_HQ = "Add Manning Plan HQ";
        public const string View_Manning_Plan_HQ = "View Manning Plan HQ";
        public const string View_Manning_Plan_HQ_CombCEO = "View Manning Plan HQ Manager"; 
        public const string View_Manning_Plan_CEO = "View Manning Plan CEO";
        public const string Add_Issue_staff_requisition = "Add Issue staff requisition"; 
        public const string Training_Action = "Training Action";
        public const string Admin = "Admin";
        public const string Rec_Action = "Recruitment Actions";
    }

自定义主体:

public CustomPrincipal(WindowsIdentity source, TBL_UserPermissions baseUser ,bool inDb, string ID) :
            base(source)
        {
            
            UserPermission = baseUser;

           
            HttpContext.Current.Session["USERID"] = ID;
        }

        public override bool IsInRole(string role)
        {
           
            bool hasPermission = false;
            if (UserPermission != null && (UserPermission.UserID != null))
            {
               
                hasPermission = db.TBL_UserPermissions.Any(up => up.TBL_Permissions.PermissionName == role && up.IsActive == true && up.UserID == UserPermission.UserID);
            }
         
         return (base.IsInRole(role) || (hasPermission));
        }

        public TBL_UserPermissions UserPermission { get; protected set; }
4

2 回答 2

0

您需要使用某种验证,一种简单的方法是在末尾添加另一个数字进行验证,并在您尝试访问页面时将其丢弃。

例如,您使用数字的总和:

对于网址 http://localhost:12997/Manning_HQ/Edit/1274

总和 = 1+2+7+4 =>14 -> 1+4 => 5

新网址将是 http://localhost:12997/Manning_HQ/Edit/12745

于 2020-05-18T16:36:00.020 回答
0

服务器端,控制器/API 代码永远不能信任来自客户端的数据。对于控制器方法,您将拥有与会话关联的经过身份验证的用户。对于每个请求,您都应该断言提供的 ID 可以由会话用户修改。API 方法将包括用于断言和识别用户的身份验证令牌,以确定他们是否正在访问适当的记录。

如果您检测到当前用户无权访问的 ID 进入,它会立即向管理员发送有关违规(用户 ID、记录 ID、日期/时间、IP 地址等)的事件日志通知并终止用户的会话。(一脚登录)系统应跟踪针对用户的这些违规行为,如果用户的帐户遭到入侵,重复尝试应锁定用户的帐户。(通常它只是一个好奇的土包子想知道是否有东西是开放的/可能的)

更新请求返回的任何数据也是如此。一切都需要验证,并且只有您允许更新的字段应该被保留。这是我建议您永远不要在客户端和服务器之间传递 EF 实体的 #1 原因。请求的有效负载可以被篡改,因此执行附加 + 修改或更新方法的代码容易受到数据篡改。

于 2020-05-19T01:09:16.750 回答