SpringBoot 之 SpringMVC 实现SQL注入过滤 完整版(支持POST请求和GET请求)解析

访客 阅读:206 2021-03-31 17:00:48 评论:0

首先请参考:SpringBoot 之 SpringMVC拦截器从Request中获取参数并解决request的请求流只能读取一次的问题

参考完上面的代码,现在开始编辑SQL注入拦截器,核心功能代码如下:

package com.digipower.erms.interceptor; 
 
import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.Enumeration; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.regex.Pattern; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import org.apache.commons.lang.StringEscapeUtils; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.core.LocalVariableTableParameterNameDiscoverer; 
import org.springframework.web.method.HandlerMethod; 
import org.springframework.web.servlet.ModelAndView; 
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 
import com.alibaba.druid.util.StringUtils; 
import com.alibaba.fastjson.JSON; 
import com.alibaba.fastjson.JSONObject; 
import com.ctc.wstx.util.StringUtil; 
import com.digipower.erms.annotation.SysLog; 
import com.digipower.erms.api.LogRecordService; 
import com.digipower.erms.common.cache.RedisUtil; 
import com.digipower.erms.common.model.Result; 
import com.digipower.erms.domain.LogRecord; 
import com.digipower.erms.request.wrapper.SQLInjectionHttpServletRequestWrapper; 
import com.digipower.erms.util.HttpContextUtils; 
import com.digipower.erms.util.HttpUtils; 
import com.digipower.erms.util.SecurityUtils; 
 
/** 
 * 全局拦截器 
 */ 
public class ErmsInterceptor extends HandlerInterceptorAdapter { 
 
    private static final Logger log = LoggerFactory.getLogger(ErmsInterceptor.class); 
     
    @Autowired 
	private LogRecordService service; 
     
    @Autowired 
	SecurityUtils securityUtils; 
 
    @Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
    	log.debug("ErmsInterceptor start pre ..."); 
    	String method = request.getMethod(); 
    	if("POST".equals(method)){ 
    		SQLInjectionHttpServletRequestWrapper wrapper = new SQLInjectionHttpServletRequestWrapper(request); 
    		String requestBody = wrapper.getRequestBodyParame(); 
    		if(!StringUtils.isEmpty(requestBody)){ 
    			//sql注入直接拦截 
				if(sqlInject(requestBody.toLowerCase())){  
					 // 补全拦截器过滤用户登入信息 
					 if (handler instanceof HandlerMethod) { 
						 HandlerMethod h = (HandlerMethod) handler; 
						 insertLogRecord(h,requestBody);  
					 } 
					response.setContentType("text/html;charset=UTF-8");   
					response.getWriter().print(JSON.toJSONString(Result.ok("-3","请求异常").setData("error-message", "参数含有非法攻击字符,已禁止继续访问")));   
					return false;   
				} 
    		}   
    	} else { 
    		Enumeration<String> names = request.getParameterNames();  
    		// 请求参数转换JSON 对象 
			List<Map> container = new ArrayList<Map>(); 
			while(names.hasMoreElements()){ 
				Map<String,String> map = new HashMap<String,String>(); 
				String key = names.nextElement(); 
				String value = request.getParameter(key); 
				map.put(key, value); 
				container.add(map); 
			} 
			String requestBody = JSON.toJSONString(container); 
			 
    		while(names.hasMoreElements()){   
    			String name = names.nextElement();   
    			String[] values = request.getParameterValues(name);   
    			for(String value: values){ 
    				//sql注入直接拦截 
    				if(sqlInject(value.toLowerCase())){ 
    					 // 补全拦截器过滤用户登入信息 
    					if(handler instanceof HandlerMethod){ 
    						HandlerMethod h = (HandlerMethod) handler; 
    						insertLogRecord(h,requestBody);  
    					} 
    					 
    					response.setContentType("text/html;charset=UTF-8");   
    					response.getWriter().print(JSON.toJSONString(Result.ok("-3","请求异常").setData("error-message", "参数含有非法攻击字符,已禁止继续访问")));   
    					return false;   
    				} 
    				// 脚本注入XSS 
    				StringEscapeUtils.escapeHtml(value); 
    				StringEscapeUtils.escapeHtml(value); 
    			}   
    		}   
    	} 
 
        //TODO  
        return true; 
    } 
 
    @Override 
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 
        super.postHandle(request, response, handler, modelAndView); 
    } 
 
    @Override 
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 
        super.afterCompletion(request, response, handler, ex); 
    } 
 
    @Override 
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
        super.afterConcurrentHandlingStarted(request, response, handler); 
    } 
     
    /** 
     *  
     * @Title: sqlInject    
     * @Description: TODO SQL 注入正在表达式(sql 函数关键字过滤) 
     * @param: @param value 
     * @param: @return       
     * @return: boolean       
     * @throws 
     */ 
    public boolean sqlInject(String value){   
        if(value == null || "".equals(value)){   
            return false;   
        }   
        String regex =".*(select|update|union|and|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|drop|execute|[+]|%).*"; 
        boolean isMatch = Pattern.matches(regex, value); 
        return isMatch;   
    } 
     
    public void insertLogRecord(HandlerMethod handlerMethod,String queryParame){ 
    	LogRecord record = new LogRecord(); 
    	SysLog sysLog = handlerMethod.getMethodAnnotation(SysLog.class); 
    	if (sysLog != null) { 
            // 注解上的描述 
        	record.setLogType(Short.valueOf("-1")); 
        	record.setLogDesc(sysLog.value()); 
        } 
    	String className = handlerMethod.getClass().getName(); 
        String methodName = handlerMethod.getMethod().getName(); 
    	record.setClassMethod(className + "." + methodName + "()"); 
    	// 请求参数 
    	record.setParames(queryParame); 
    	// 请求地址 
        HttpServletRequest request = HttpContextUtils.getRequest(); 
        String ip = HttpUtils.getIpAddress(request); 
        record.setIpAddress(ip); 
         
        // 操作用户 
       String username = securityUtils.getAuthUserPin(request); 
       record.setUsername(username); 
        
       // 创建时间 
       record.setCreateTime(new Date());  
       service.insert(record); 
    } 
} 

springboot 配置拦截器:

package com.digipower.ucas.config; 
  
import java.util.ArrayList; 
import java.util.List; 
  
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.http.converter.HttpMessageConverter; 
import org.springframework.web.servlet.config.annotation.EnableWebMvc; 
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 
  
import io.swagger.annotations.ApiOperation; 
import springfox.documentation.builders.ApiInfoBuilder; 
import springfox.documentation.builders.ParameterBuilder; 
import springfox.documentation.builders.PathSelectors; 
import springfox.documentation.builders.RequestHandlerSelectors; 
import springfox.documentation.schema.ModelRef; 
import springfox.documentation.service.ApiInfo; 
import springfox.documentation.service.Contact; 
import springfox.documentation.service.Parameter; 
import springfox.documentation.spi.DocumentationType; 
import springfox.documentation.spring.web.plugins.Docket; 
import springfox.documentation.swagger2.annotations.EnableSwagger2; 
  
@Configuration 
@EnableSwagger2 
@EnableWebMvc 
public class SwaggerConfig extends WebMvcConfigurerAdapter { 
  
	@Override 
	public void addResourceHandlers(ResourceHandlerRegistry registry) { 
		registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); 
		registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); 
	} 
	 
	// 定义json 转换器 
	@Override 
	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
		// TODO Auto-generated method stub 
		super.configureMessageConverters(converters); 
	} 
  
	@Bean 
	public Docket buildDocket() { 
  
		ParameterBuilder tokenPar = new ParameterBuilder(); 
		List<Parameter> pars = new ArrayList<Parameter>(); 
		tokenPar.name("X-CSRF-TOKEN").description("令牌").modelRef(new ModelRef("string")).parameterType("header") 
				.required(false).build(); 
		pars.add(tokenPar.build()); 
  
		return new Docket(DocumentationType.SWAGGER_2).select() 
				.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any()) 
				.build().globalOperationParameters(pars).apiInfo(buildApiInf()); 
	} 
  
	 
  
	private ApiInfo buildApiInf() { 
		return new ApiInfoBuilder().title("深圳市世纪伟图科技开发有限公司 - 城建档案系统").termsOfServiceUrl("http://www.digipower.cn/") 
				.description("API接口") 
				.contact(new Contact("digipower", "http://www.digipower.cn/", "[email protected]")) 
				.version("2.0").build(); 
  
	} 
	 
	    //SQL注入拦截器 
		@Bean 
		public ErmsInterceptor sqlInjectInterceptor () { 
			return new ErmsInterceptor (); 
		} 
	  
		@Override 
		public void addInterceptors(InterceptorRegistry registry) {// 2 
			registry.addInterceptor(sqlInjectInterceptor()); 
		} 
}

 

声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

发表评论
搜索
排行榜
KIKK导航

KIKK导航

关注我们