Web安全漏洞問題總結
1 問題描述
[步驟]
例如經銷商id =57029,在後臺通過投放抓包到投放介面,並篡改介面資料,可以給經銷商id =57024 新增廠商 = 東風乘用車 的投放需求(57024的經銷商並沒有主營 496的廠商車系);同時也可以通過介面隨意篡改任何經銷商的投放。
介面:http://dev60.pcauto.com.cn:8080/dealer/advertising/createOrUpdateDealerLaunch.do
引數:
dealerId=57024&startDate=2018-11-30&endDate=2018-12-08&budget=350.0&manuId=496&serialId=10821&serialId=11021&serialId=7679&serialId=12523&serialId=21223&serialId=14242&serialId=10811&serialId=11747&serialId=21603&serialId=4445&serialId=10856&serialId=3904&serialId=4565&open=0&open=0&open=1&open=1&open=1&open=1&open=1&open=1&open=1&open=1&open=1&open=1&open=1&serialName=%E4%B8%9C%E9%A3%8EA9&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9EA30&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9EA60&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9EAX3&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9EAX4&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9EAX5&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9EAX7&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9EE30&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9EE70&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9EH30&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9EL60&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9ES30(%E5%81%9C%E5%94%AE)&serialName=%E4%B8%9C%E9%A3%8E%E9%A3%8E%E7%A5%9ETai-Concept(%E6%A6%82%E5%BF%B5%E8%BD%A6)&launchId=305
解決思路:
主介面入口的時候後端生成加密的token繫結使用者id,通過cookies,或者session把請求的token帶到頁面端儲存。後面每一次請求都把頁面端從後臺帶過來的token進行url的攔截,然後取出後端快取中的token與使用者Id做校驗。其他資料篡改,要做相應的前後臺校驗。
入口
public String addLoginDealer(long dealerId, HttpServletResponse response){ String token = T.genetateToken(); ValueOperations<String, String> opsForValue = redisTemplate.opsForValue(); opsForValue.set(String.valueOf(dealerId) + "-token", token, 1800, TimeUnit.SECONDS); String salt = DealerTokenKey.getDealerSalt(); token = salt.charAt(1) + salt.charAt(3) + token + salt.charAt(6) + salt.charAt(4); String mdToken = MD5Util.encrypt(token); Cookie cookie = new Cookie(DealerTokenKey.getCookiNameToken(), mdToken); cookie.setMaxAge(1800); cookie.setPath("/"); response.addCookie(cookie); return token; }
攔截校驗
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String dealerId = getDealerId(request); if(T.isBlank(dealerId)) { StringBuffer requestURL = request.getRequestURL(); logger.info("url:="+requestURL.toString()+": dealerId:="+dealerId); response.sendRedirect(PropertiestTool.getInstance().get("local_domain")+"/dealer/index/prev.do"); return false; } ValueOperations<String, String> opsForValue = redisTemplate.opsForValue(); String token = opsForValue.get(String.valueOf(dealerId) + "-token"); logger.info("redis check login:="+token); if(T.isBlank(token)){ response.sendRedirect(PropertiestTool.getInstance().get("local_domain")+"/dealer/index/prev.do"); return false; } Cookie cookie = getCookieValue(request, DealerTokenKey.getCookiNameToken()); if (cookie == null){ response.sendRedirect(PropertiestTool.getInstance().get("local_domain")+"/dealer/index/prev.do"); return false; } String cookieValue = cookie.getValue(); logger.info("dealerId:" + dealerId + " - cookie value:=" + cookieValue); if(T.isBlank(cookieValue)){ response.sendRedirect(PropertiestTool.getInstance().get("local_domain")+"/dealer/index/prev.do"); return false; } String salt = DealerTokenKey.getDealerSalt(); String mdToken = MD5Util.encrypt(salt.charAt(1) + salt.charAt(3) + token + salt.charAt(6) + salt.charAt(4)); if (!cookieValue.equals(mdToken)){ response.sendRedirect(PropertiestTool.getInstance().get("local_domain")+"/dealer/index/prev.do"); return false; } opsForValue.set(String.valueOf(dealerId) + "-token", token, 1800, TimeUnit.SECONDS); cookie.setMaxAge(1800); cookie.setPath("/"); response.addCookie(cookie); return true; }