content: package com.ctg.test.cros.springbootcros.filter;
  
  
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.util.StringUtils;
  
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletRequestWrapper;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Map;
  import java.util.Set;
  
  /**
   * 防止sql注入,xss攻击
   * 前端可以对输入信息做预处理，后端也可以做处理。
   */
  public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
      private final Logger log = LoggerFactory.getLogger(getClass());
      private static String key = "and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+";
      private static Set<String> notAllowedKeyWords = new HashSet<String>(0);
      private static String replacedString="INVALID";
      static {
          String keyStr[] = key.split("\\|");
          for (String str : keyStr) {
              notAllowedKeyWords.add(str);
          }
      }
  
      private String currentUrl;
  
      public XssHttpServletRequestWrapper(HttpServletRequest servletRequest) {
          super(servletRequest);
          currentUrl = servletRequest.getRequestURI();
      }
  
  
      /**覆盖getParameter方法，将参数名和参数值都做xss过滤。
       * 如果需要获得原始的值，则通过super.getParameterValues(name)来获取
       * getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
       */
      @Override
      public String getParameter(String parameter) {
          String value = super.getParameter(parameter);
          if (value == null) {
              return null;
          }
          return cleanXSS(value);
      }
      @Override
      public String[] getParameterValues(String parameter) {
          String[] values = super.getParameterValues(parameter);
          if (values == null) {
              return null;
          }
          int count = values.length;
          String[] encodedValues = new String[count];
          for (int i = 0; i < count; i++) {
              encodedValues[i] = cleanXSS(values[i]);
          }
          return encodedValues;
      }
      @Override
      public Map<String, String[]> getParameterMap(){
          Map<String, String[]> values=super.getParameterMap();
          if (values == null) {
              return null;
          }
          Map<String, String[]> result=new HashMap<>();
          for(String key:values.keySet()){
              String encodedKey=cleanXSS(key);
              int count=values.get(key).length;
              String[] encodedValues = new String[count];
              for (int i = 0; i < count; i++){
                  encodedValues[i]=cleanXSS(values.get(key)[i]);
              }
              result.put(encodedKey,encodedValues);
          }
          return result;
      }
      /**
       * 覆盖getHeader方法，将参数名和参数值都做xss过滤。
       * 如果需要获得原始的值，则通过super.getHeaders(name)来获取
       * getHeaderNames 也可能需要覆盖
       */
      @Override
      public String getHeader(String name) {
          String value = super.getHeader(name);
          if (value == null) {
              return null;
          }
          return cleanXSS(value);
      }
  
      private String cleanXSS(String valueP) {
          // You'll need to remove the spaces from the html entities below
          String value = valueP.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
          value = value.replaceAll("<", "& lt;").replaceAll(">", "& gt;");
          value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
          value = value.replaceAll("'", "& #39;");
          value = value.replaceAll("eval\\((.*)\\)", "");
          value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\"");
          value = value.replaceAll("script", "");
          value = cleanSqlKeyWords(value);
          return value;
      }
  
      private String cleanSqlKeyWords(String value) {
          String paramValue = value;
          for (String keyword : notAllowedKeyWords) {
              if (paramValue.length() > keyword.length() + 4
                      && (paramValue.contains(" "+keyword)||paramValue.contains(keyword+" ")||paramValue.contains(" "+keyword+" "))) {
                  paramValue = StringUtils.replace(paramValue, keyword, replacedString);
                  log.error(this.currentUrl + "已被过滤，因为参数中包含不允许sql的关键词(" + keyword
                          + ")"+";参数："+value+";过滤后的参数："+paramValue);
              }
          }
          return paramValue;
      }
  
  }
  