19 lines
23 KiB
Plaintext
19 lines
23 KiB
Plaintext
Index: securityControl-common/securityControl-common-security/src/main/java/com/securityControl/common/security/interceptor/ParamSecureHandler.java
|
||
IDEA additional info:
|
||
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
|
||
<+>package com.securityControl.common.security.interceptor;\r\n\r\nimport com.alibaba.fastjson2.JSON;\r\nimport com.github.pagehelper.util.StringUtil;\r\nimport com.securityControl.common.core.constant.SecurityConstants;\r\nimport com.securityControl.common.core.context.SecurityContextHolder;\r\nimport com.securityControl.common.core.utils.JwtUtils;\r\nimport com.securityControl.common.core.utils.ServletUtils;\r\nimport com.securityControl.common.core.utils.StringUtils;\r\nimport com.securityControl.common.core.utils.aes.DateTimeHelper;\r\nimport com.securityControl.common.core.utils.aes.StringHelper;\r\nimport com.securityControl.common.core.utils.ip.IpUtils;\r\nimport com.securityControl.common.core.web.domain.AjaxResult;\r\nimport com.securityControl.common.security.enums.UrlEnums;\r\nimport com.securityControl.common.security.utils.SafeUtil;\r\nimport com.securityControl.common.security.utils.Sm3Utils;\r\nimport com.securityControl.common.security.utils.XssRequestWrapper;\r\nimport com.securityControl.system.api.RemoteLogService;\r\nimport com.securityControl.system.api.domain.SysOperLog;\r\nimport com.sgcc.isc.framework.common.constant.Constants;\r\nimport com.sgcc.isc.service.adapter.factory.AdapterFactory;\r\nimport com.sgcc.isc.service.adapter.helper.IResourceService;\r\nimport lombok.extern.slf4j.Slf4j;\r\nimport org.springframework.beans.factory.annotation.Autowired;\r\nimport org.springframework.scheduling.annotation.Async;\r\nimport org.springframework.util.AntPathMatcher;\r\nimport org.springframework.util.PathMatcher;\r\nimport org.springframework.web.servlet.AsyncHandlerInterceptor;\r\n\r\nimport javax.servlet.ServletRequest;\r\nimport javax.servlet.http.HttpServletRequest;\r\nimport javax.servlet.http.HttpServletResponse;\r\nimport javax.servlet.http.HttpSession;\r\nimport java.io.*;\r\nimport java.nio.charset.StandardCharsets;\r\nimport java.util.*;\r\n\r\n/**\r\n * @author bonus\r\n * @data 2023/2/6 17:22\r\n * @description 安全参数验证\r\n */\r\n@Slf4j\r\npublic class ParamSecureHandler implements AsyncHandlerInterceptor {\r\n @Autowired\r\n private final PathMatcher pathMatcher = new AntPathMatcher();\r\n\r\n //@Autow\r\n public static String rnd = null;\r\n\r\n\r\n private String whiteURL =\"http://27.196.164.56:21001/\";\r\n\r\n// private String whiteURL=\"http://localhost:63343/\";\r\n\r\n // private String whiteURL =\"http://27.196.156.43:9988/\";\r\n\r\n @Autowired\r\n private RemoteLogService remoteLogService;\r\n\r\n private static Map<String, List<Double>> requestLogMap = null;\r\n\r\n IResourceService resourceService = (IResourceService) AdapterFactory.getInstance(Constants.CLASS_RESOURCE);\r\n\r\n\r\n @Override\r\n public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {\r\n System.out.println(\"进入了拦截器\");\r\n System.err.println(request.getRequestURI());\r\n if(Objects.equals(\"/pot/superStatistics/importExcel\",request.getRequestURI()) ||\r\n Objects.equals(\"/pot/todayTask/uploadNoticeVio\",request.getRequestURI()) ||\r\n Objects.equals(\"/pot/superStatistics/editUploadNoticeVio\",request.getRequestURI()) ||\r\n Objects.equals(\"/pot/todayTask/uploadExceptionReport\",request.getRequestURI()) ||\r\n Objects.equals(\"/getUserTicket\",request.getRequestURI()) ||\r\n Objects.equals(\"/\",request.getRequestURI()) ||\r\n Objects.equals(\"/pot/todayTask/uploadExceptionReport\",request.getRequestURI()) ||\r\n Objects.equals(\"/pot/superStatistics/uploadNoticeVioRect\",request.getRequestURI()) ||\r\n Objects.equals(\"/pot/device/importExcel\",request.getRequestURI()) ||\r\n Objects.equals(\"/pot/TRiskPressDropRate/importExcel\",request.getRequestURI()) ||\r\n Objects.equals(\"pot/early/exportToExcel\",request.getRequestURI()) ||\r\n Objects.equals(\"/sys/dict/getDictList\",request.getRequestURI()) ||\r\n Objects.equals(\"/api/ballrisk/findBallGb\",request.getRequestURI()) || //外部接口的过滤\r\n Objects.equals(\"/api/ballrisk/findDeviceStatus\",request.getRequestURI()) || //外部接口的过滤\r\n Objects.equals(\"/api/ballrisk/getDeviceState\",request.getRequestURI()) || //外部接口的过滤\r\n Objects.equals(\"/sys/menu/getAllMenuList\",request.getRequestURI()) || //外部接口的过滤\r\n request.getRequestURI().contains(\"/file/getFile/\") || //外部接口的过滤\r\n request.getRequestURI().contains(\"/export/\") || //外部接口的过滤\r\n Objects.equals(\"/pot/video/upload\",request.getRequestURI()) ||\r\n request.getRequestURI().contains(\"/sys/userManage/info/\") || //外部接口的过滤\r\n Objects.equals(\"/sys/menu/getMenuList\",request.getRequestURI())){ // 过滤文件上传功能和菜单管理\r\n return true;\r\n }\r\n if(StringUtils.isNotBlank(request.getRequestURI())){\r\n if(request.getRequestURI().contains(\"/files/\")){\r\n return true;\r\n }\r\n }\r\n XssRequestWrapper requestWrapper = new XssRequestWrapper(request);\r\n String requestUrl = requestWrapper.getRequestURI();\r\n /*if (StringUtil.isEmpty(requestUrl.trim())) {\r\n return false;\r\n }*/\r\n /**\r\n * 防止refer篡改\r\n */\r\n String referUrl= request.getHeader(\"Referer\");\r\n if(StringHelper.isNotEmpty(referUrl)){\r\n if(referUrl.contains(\"/ahsfsaq/\")){\r\n requestUrl=referUrl.split(\"21001\")[0];\r\n requestUrl=requestUrl+\"21001/\";\r\n }\r\n }\r\n if(!whiteURL.equals(referUrl)){\r\n returnJson(response,\"请求来源不正确!\",500);\r\n return false;\r\n }\r\n /**\r\n * 白名单中不验证参数\r\n */\r\n /* boolean doFilter = isWhiteURL(requestUrl);\r\n if (doFilter) {\r\n return true;\r\n }*/\r\n if (!requestWrapper.isChecked()) {\r\n log.error(\"输入值非法{}\", requestWrapper.getQueryString());\r\n returnJson(response,\"输入值非法!\",500);\r\n return false;\r\n }\r\n System.err.println(JSON.toJSONString(request.getParameterMap()));\r\n /**\r\n * 跨站点攻击\r\n */\r\n\r\n /* boolean checkXss = checkXss(request, requestUrl);\r\n if (!checkXss) {\r\n //resultError(HttpConstants.HTTP_RES_CODE_400.getKey(), ctx, \"请求非法!\");\r\n throw new BindException(null, \"请求非法!\");\r\n return false;\r\n }*/\r\n /**\r\n * 获取所有跳转路径参数,保留传入下个界面\r\n */\r\n Map<String, String[]> map = requestWrapper.getParameterMap();\r\n boolean checkParameterMap = checkParameterMap(map, requestUrl);\r\n if (!checkParameterMap) {\r\n //resultError(HttpConstants.HTTP_RES_CODE_400.getKey(), ctx, \"输入值非法!\");\r\n// throw new ServiceException(\"输入值非法!\",500);\r\n returnJson(response,\"输入值非法\",500);\r\n return false;\r\n }\r\n /**\r\n * 同地址请求验证\r\n */\r\n String ckval = request.getHeader(\"ckval\");\r\n String currentRequest = request.getRemoteAddr() + \":\" + requestUrl + \"?ckval=\" + ckval;\r\n\r\n// boolean checkSameUrl = checkSameUrl(currentRequest, requestWrapper);\r\n// if (!checkSameUrl) {\r\n// log.info(\"{}请求重复,{}\", currentRequest, rnd);\r\n// //resultError(HttpConstants.HTTP_RES_CODE_400.getKey(), ctx, \"请求重复!\");\r\n// returnJson(response,\"请求重复\",500);\r\n// }\r\n /**\r\n * 检查数据流参数\r\n */\r\n String readerParam = requestWrapper.getReaderParam();\r\n if (requestUrl.indexOf(\"uploadFile\") < 0 && requestUrl.indexOf(\"uploadImage\") < 0) {// 判断是否是文件上传,是不对流参数进行验证\r\n boolean checkReader = checkReader(readerParam, requestUrl);\r\n if (!checkReader) {\r\n returnJson(response,\"请求重复\",500);\r\n return false;\r\n }\r\n\r\n }\r\n if (!sm3Check(request)) {\r\n returnJson(response,\"请求参数丢失\",500);\r\n return false;\r\n }\r\n\r\n if(!checkIsYq(request,requestWrapper)){\r\n returnJson(response,\"请求越权,请检查用户权限\",500);\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n\r\n public static void returnJson(HttpServletResponse response,String msg,int code){\r\n PrintWriter writer=null;\r\n response.setCharacterEncoding(\"UTF-8\");\r\n response.setContentType(\"applicatiopn/json;charset=utf-8\");\r\n AjaxResult a=AjaxResult.error(code,msg);\r\n String res=JSON.toJSONString(a);\r\n try {\r\n writer=response.getWriter();\r\n writer.println(res);\r\n }catch (IOException e){\r\n e.printStackTrace();\r\n }\r\n }\r\n\r\n /**\r\n * 判断是否越权\r\n */\r\n private boolean checkIsYq(HttpServletRequest request,XssRequestWrapper requestWrapper) throws Exception {\r\n String requestURI = request.getRequestURI();\r\n String[] headUrls = requestURI.split(\"/\");\r\n String url = \"/\" + headUrls[1]+\"/\" + headUrls[2] + \"/**\";\r\n Boolean result = true;\r\n String token = requestWrapper.getParameter(\"token\");\r\n if (StringUtils.isNotEmpty(token)) {\r\n String userId = JwtUtils.getIscUserId(token);\r\n System.out.println(\"拦截器userId:\" + userId);\r\n if (StringUtil.isEmpty(userId)) {\r\n result = false;\r\n } else {\r\n result = resourceService.hasPermitURLObj(userId, \"9b4483c383538275018615493e1451ea\", url);\r\n }\r\n System.out.println(\"==================越狱记录:========================userId:\" + userId + \"============是否越狱:\" + result);\r\n } else {\r\n result = false;\r\n }\r\n\r\n if (!result) {\r\n //记录日志 鹏飞\r\n addExceedsAccessLog(url, token);\r\n return false;\r\n //添加弹框\r\n }\r\n return true;\r\n }\r\n\r\n\r\n private void addExceedsAccessLog(String url, String token) {\r\n SysOperLog sysOperLog = new SysOperLog();\r\n sysOperLog.setGrade(\"越权访问\");\r\n sysOperLog.setOperName(JwtUtils.getUserName(token));\r\n sysOperLog.setTimes(DateTimeHelper.getNowTime());\r\n sysOperLog.setRoleName(\"继远管理员\");\r\n sysOperLog.setDeptName(\"建设分公司\");\r\n sysOperLog.setOperIp(IpUtils.getIpAddr(ServletUtils.getRequest()));\r\n UrlEnums[] enums = UrlEnums.values();\r\n for (UrlEnums anEnum : enums) {\r\n if (url.startsWith(anEnum.getUrl())) {\r\n sysOperLog.setTitle(anEnum.getInfo());\r\n }\r\n }\r\n if (StringUtils.isEmpty(sysOperLog.getTitle())) {\r\n sysOperLog.setTitle(\"系统管理\");\r\n }\r\n sysOperLog.setRequestMethod(\"\");\r\n sysOperLog.setMethod(\"\");\r\n sysOperLog.setBusinessType(1);\r\n sysOperLog.setOperUrl(\"\");\r\n sysOperLog.setOperParam(\"\");\r\n sysOperLog.setDetail(\"用户越权访问地址:\" + url);\r\n sysOperLog.setLogType(\"系统日志\");\r\n sysOperLog.setSysMenu(\"\");\r\n sysOperLog.setStatus(1);\r\n remoteLogService.saveLogs(sysOperLog, SecurityConstants.INNER);\r\n }\r\n\r\n\r\n /**\r\n * 简单的xss跨站点检查\r\n *\r\n * @param request\r\n * @param requestUrl\r\n * @return\r\n */\r\n /*private boolean checkXss(HttpServletRequest request, String requestUrl) {\r\n String host = request.getHeader(\"Host\");\r\n String localAddr = foundationConfig.getRequestUrl().getLocalAddr();//request.getLocalAddr();\r\n String remoteHost = foundationConfig.getRequestUrl().getRemoteHost();//request.getRemoteHost();\r\n String referer = request.getHeader(\"Referer\");\r\n log.debug(\"获取到host:{},localAddr:{},remoteHost:{},referer:{}\", host, localAddr, remoteHost, referer);\r\n if (StringUtil.isEmpty(host) || StringUtil.isEmpty(localAddr)\r\n || StringUtil.isEmpty(remoteHost) || StringUtil.isEmpty(referer)) {\r\n return false;\r\n }\r\n // 如果请求地址为空则直接返回false\r\n if (requestUrl == null) {\r\n log.info(\"当前请求地址不存在\");\r\n return false;\r\n }\r\n String localAddr2 = request.getLocalAddr();\r\n String remoteHost2 = request.getRemoteHost();\r\n if (referer.indexOf(remoteHost) == -1 && referer.indexOf(remoteHost2) == -1) {\r\n return false;\r\n }\r\n if (host.indexOf(localAddr) == -1 && host.indexOf(localAddr2) == -1) {\r\n return false;\r\n }\r\n // 逻辑: 判断SERVICE_TYPES数组中 所有元素 是否有一个能够通过验证\r\n // 循环SERVICE_TYPES\r\n // 判断当前变量是否存在于referer,判断当前变量在不存在于referer,是否存在于requestUrl\r\n // 存在则返回true,结束循环\r\n // 不存在,返回false,提示当前来源不是本站请求\r\n for (String headerURL : foundationConfig.getHeaderUrls()) {\r\n if (referer.indexOf(headerURL) != -1 || requestUrl.indexOf(headerURL) != -1) {\r\n return true;\r\n }\r\n }\r\n log.info(\"当前请求来源不是本站请求!请求地址:\" + requestUrl + \".请检查请求的URL是否正确!\");\r\n return false;\r\n }*/\r\n\r\n /* */\r\n\r\n /**\r\n * 判断白名单\r\n *\r\n * @param currentURL\r\n * @return\r\n */\r\n private boolean isWhiteURL(String currentURL) {\r\n // for (String whiteURL : foundationConfig.getWhiteUrls()) {\r\n if (pathMatcher.match(whiteURL, currentURL)) {\r\n log.info(\"白名单过滤: [{}] 匹配 [{}] \", whiteURL, currentURL);\r\n return true;\r\n }\r\n log.info(\"白名单过滤: [{}] 未匹配 [{}]\", whiteURL, currentURL);\r\n // }\r\n return false;\r\n }\r\n\r\n /**\r\n * 参数校验\r\n *\r\n * @param request\r\n * @return\r\n */\r\n public static boolean sm3Check(HttpServletRequest request) {\r\n Map<String, String> map = new LinkedHashMap<>();\r\n\r\n request.getParameterMap().forEach((key, value) -> {\r\n if (!Objects.equals(key, \"token\")) {\r\n map.put(key, String.join(\" \", value));\r\n }\r\n });\r\n\r\n String header = request.getHeader(\"encrypt\");\r\n String json = JSON.toJSONString(map);\r\n if (\"{}\".equals(json)) {\r\n json = getBodyString(request);\r\n }\r\n String str = Sm3Utils.encrypt(json);\r\n return str.equalsIgnoreCase(header);\r\n }\r\n\r\n /**\r\n * 检查所有页面输入的参数是否安全 request.getParameterMap()\r\n *\r\n * @param map\r\n * @param requestUrl\r\n */\r\n public static boolean checkParameterMap(Map<String, String[]> map, String requestUrl) {\r\n rnd = null;\r\n if (map != null && map.size() > 0) {\r\n Iterator<Map.Entry<String, String[]>> iterator = map.entrySet().iterator();\r\n String value = \"\";// 参数值\r\n while (iterator.hasNext()) {\r\n value = \"\";\r\n Map.Entry<String, String[]> entry = iterator.next();\r\n String pname = (String) entry.getKey(); // 参数名\r\n if (Objects.equals(\"token\", pname)) {\r\n continue;\r\n }\r\n Object objValue = entry.getValue(); // 数组\r\n if (null == objValue) {\r\n value = \"\";\r\n } else if (objValue instanceof String[]) {\r\n String[] values = (String[]) objValue;\r\n for (int i = 0; i < values.length; i++) {\r\n value = values[i] + \",\";\r\n }\r\n if (value.length() > 0) {\r\n value = value.substring(0, value.length() - 1);\r\n }\r\n }\r\n if (\"rnd\".equals(pname)) {\r\n rnd = value;\r\n }\r\n if (SafeUtil.checkSafeSql(value)) {\r\n log.info(\"请求失败,当前请求参数不安全!请求地址:\\n\" + requestUrl + \"\\n不安全参数:\" + pname + \":\" + value);\r\n return false;\r\n }\r\n if (SafeUtil.checkSpecial(value)) {\r\n log.info(\"请求失败,当前请求参数包含特殊字符!请求地址:\\n\" + requestUrl + \"\\n特殊字符参数:\" + pname + \":\" + value);\r\n return false;\r\n }\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * 通过rnd随机参数判断相同url是否多次请求访问\r\n *\r\n * @param currentRequest\r\n * @param requestWrapper\r\n * @return\r\n */\r\n public static boolean checkSameUrl(String currentRequest, XssRequestWrapper requestWrapper) {\r\n if (rnd != null && rnd.length() > 0) {\r\n try {\r\n double newRnd = Double.parseDouble(rnd);\r\n /**\r\n * 当为空时,新增请求时间记录,第一次请求,放行,允许查询\r\n */\r\n HttpSession session = requestWrapper.getSession();\r\n Object obj = session.getAttribute(\"requestLogMap\");\r\n if (obj == null) {\r\n requestLogMap = new HashMap<String, List<Double>>();\r\n } else {\r\n requestLogMap = (Map<String, List<Double>>) obj;\r\n }\r\n\r\n List<Double> list = requestLogMap.get(currentRequest);\r\n if (list == null) {\r\n list = new ArrayList<Double>();\r\n } else {\r\n for (Double oldRnd : list) {\r\n if (oldRnd == newRnd) {\r\n log.info(\"请求失败,当前请求已过期!请重新登录!您的请求地址:\\n\" + currentRequest);\r\n return false;\r\n }\r\n }\r\n }\r\n list.add(newRnd);\r\n requestLogMap.put(currentRequest, list);\r\n if (session.getAttribute(\"requestLogMap\") != null) {\r\n session.removeAttribute(\"requestLogMap\");\r\n }\r\n session.setAttribute(\"requestLogMap\", requestLogMap);\r\n } catch (NumberFormatException e) {\r\n log.info(\"rnd参数格式化错误 请检查\");\r\n return false;\r\n }\r\n } else {\r\n log.info(\"请求失败,rnd参数不存在!请重新登录!您的请求地址:\\n\" + currentRequest);\r\n return true;\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * 检查所有页面输入的参数是否安全 request.getReader()\r\n *\r\n * @param readerParam\r\n * @param requestUrl\r\n */\r\n public static boolean checkReader(String readerParam, String requestUrl) {\r\n if (SafeUtil.checkScript(readerParam)) {\r\n log.info(\"请求失败,当前请求参数不安全!请求地址:\\n\" + requestUrl + \"\\n不安全参数:数据流:\" + readerParam);\r\n return false;\r\n }\r\n return true;\r\n }\r\n\r\n @Override\r\n public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)\r\n throws Exception {\r\n SecurityContextHolder.remove();\r\n }\r\n\r\n public static String getBodyString(HttpServletRequest request) {\r\n StringBuilder sb = new StringBuilder();\r\n InputStream inputStream = null;\r\n BufferedReader reader = null;\r\n try {\r\n inputStream = request.getInputStream();\r\n reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));\r\n String line;\r\n while ((line = reader.readLine()) != null) {\r\n sb.append(line);\r\n }\r\n } catch (IOException e) {\r\n e.printStackTrace();\r\n } finally {\r\n if (inputStream != null) {\r\n try {\r\n inputStream.close();\r\n } catch (IOException e) {\r\n e.printStackTrace();\r\n }\r\n }\r\n if (reader != null) {\r\n try {\r\n reader.close();\r\n } catch (IOException e) {\r\n e.printStackTrace();\r\n }\r\n }\r\n }\r\n return StringUtils.isBlank(sb.toString()) ? \"{}\" : sb.toString();\r\n }\r\n}\r\n
|
||
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
|
||
<+>UTF-8
|
||
===================================================================
|
||
--- securityControl-common/securityControl-common-security/src/main/java/com/securityControl/common/security/interceptor/ParamSecureHandler.java (revision 2211f3d71c7bfb90f9432b55cd2121b4777fdb40)
|
||
+++ securityControl-common/securityControl-common-security/src/main/java/com/securityControl/common/security/interceptor/ParamSecureHandler.java (date 1690277195587)
|
||
@@ -105,7 +105,7 @@
|
||
*/
|
||
String referUrl= request.getHeader("Referer");
|
||
if(StringHelper.isNotEmpty(referUrl)){
|
||
- if(referUrl.contains("/ahsfsaq/")){
|
||
+ if(referUrl.contains("/ahsfs")){
|
||
requestUrl=referUrl.split("21001")[0];
|
||
requestUrl=requestUrl+"21001/";
|
||
}
|