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

首先请参考: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/", "digiservices@digipower.com"))
				.version("2.0").build();
 
	}
	
	    //SQL注入拦截器
		@Bean
		public ErmsInterceptor sqlInjectInterceptor () {
			return new ErmsInterceptor ();
		}
	 
		@Override
		public void addInterceptors(InterceptorRegistry registry) {// 2
			registry.addInterceptor(sqlInjectInterceptor());
		}
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值