XSS filter Filter realizes the whole process

Requirements:
Filter the content entered by the user, escape special characters, and prevent some XSS attacks.
Project basis:
The front-end uses form+ajax to submit data, the back-end uses the SpringMVC framework, and the method annotated with @RequestMapping receives front-end parameters. Among them, multipart/form-data is used to transfer files.
Implementation steps:
1. Implement the XSSFilter class
2. Implement the XssHttpServletRequestWraper class
3. Register the filter in web.xml

1. Implement XssFilter

public class XssFilter implements Filter{
    
    
	//	为了解决multipart/form-data过滤器过滤之后controller接收不到数据的问题
	//如果没有用到,可以把相关内容删除去
	private MultipartResolver multipartResolver=null;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException{
    
    
		//注入bean
		multipartResolver=(MultipartResolver)ApplicationContextUtils.getApplicationContext().getBean("multipartResolver",MultipartResolver.class);
	}
	
	@Override
	public void doFilter(ServletRequest request , ServletResponse response , FilterChain chain) 
			throws IOException , ServletException{
    
    
		String contentType=request.getContentType();
		if(contentType!=null && contentType.contains("multipart/form-data")){
    
    
			//form-data过滤
			MultipartHttpServletRequest multipartRequest=multipartResolver.resolveMultipart((HttpServletRequest) request);
			XssHttpServletRequestWraper xssRequest=new XssHttpServletRequestWraper(multipartRequest);
			chain.doFilter(xssRequest, response);
		}else{
    
    
			//普通过滤
			XssHttpServletRequestWraper xssRequest=new XssHttpServletRequestWraper((HttpServletRequest)request);
			chain.doFilter(xssRequest, response);
		}
	}
	
	@Override
	public void destroy(){
    
    
		
	}	
}

Among them, if you want to filter multipart/form-data, in addition to the content of the above filters, you must also write ApplicationContextUtils.class and register beans in the spring configuration file

The content of ApplicationContextUtils.class is:

//对Spring容器进行各种上下文操作的工具类
public class ApplicationContextUtils implements ApplicationContextAware{
    
    
	
	private static ApplicationContext context;

	@Override
	public void setApplicationContext(ApplicationContext context) throws BeansException {
    
    
		ApplicationContextUtils.context = context;
	}
	
	public static ApplicationContext getApplicationContext(){
    
    
		return context;
	}
	//根据Bean名称获取Bean对象
	public static Object getBean(String beanName){
    
    
		return context.getBean(beanName);
	}
	
	public static Object getMassage(String key){
    
    
		return context.getMessage(key, null,Locale.getDefault());
	}
}

The registration content in ApplicationContext.xml is:

	<!-- =========================注册文件上传 -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 文件上传大小限制 -->
		<property name="maxUploadSize">
			<value>104857600</value>
		</property>
		<property name="defaultEncoding">
			<value>UTF-8</value>
		</property>
	</bean>
	
	<bean id="applicationContextUtils" class="ApplicationContextUtils在项目存放的位置" lazy-init="false" />

2. Implement the XssHttpServletRequestWraper class

public class XssHttpServletRequestWraper extends HttpServletRequestWrapper{
    
    
	
	public XssHttpServletRequestWraper(HttpServletRequest servletRequest){
    
    
		super(servletRequest);
	}
	
	@Override
	public String getHeader(String name){
    
    
		return super.getHeader(name);
	}
	
	@Override
	public String getParameter(String name){
    
    
		String value = super.getParameter(name);
		return xssEncode(value);
	}
	
	//对以FormData形式提交,Content-Type:application/x-www-from-urlencoded参数过滤
	@Override
	public String[] getParameterValues(String name){
    
    
		String[] values=super.getParameterValues(name);
		if(values==null){
    
    
			return null;
		}
		int count=values.length;
		String[] encodeValues=new String[count];
		for(int i=0;i<count;i++){
    
    
			encodeValues[i]=xssEncode(values[i]);
		}
		return encodeValues;
	}
	
	/*过滤策略:把特殊字符转为HTML实体编码,
	*这样存在数据库里较安全
	*返回给前端时会被js解析为正常字符,不影响查看*/
	public static String xssEncode(String str){
    
    
		if(str == null || str.isEmpty()){
    
    
			return str;
		}
		str = str.replaceAll(";", "&#59;");
		str = str.replaceAll("<", "&#60;").replaceAll(">", "&#62;");
		str = str.replaceAll("\\(", "&#40;").replaceAll("\\)", "&#41;");
		str = str.replaceAll("'", "&#39;").replaceAll("\"", "&#34;");
		str = str.replaceAll("\\$", "&#36;");
		str = str.replaceAll("%", "&#37;");
		str = str.replaceAll("\\/", "&#47;").replaceAll("\\\\", "&#92;");
		str = str.replaceAll(":", "&#58;");
		str = str.replaceAll("\\?", "&#63;").replaceAll("@", "&#64;");
		str = str.replaceAll("\\^", "&#94;");
		return str;
	}
}

3. Register the filter in web.xml:
preferably after the character filter

<filter>
	<filter-name>XssFilter</filter-name>
	<filter-class>XssFilter在项目存放的位置</filter-class>
</filter>
<filter-mapping>
	<filter-name>XssFilter</filter-name>
	<url-partten>/*<url-partten>
	<dispatcher>REQUEST</dispatcher>
</filter-mapping>

From here, the implementation and configuration of the filter is complete. After inputting at the front end
<script>alert("1");</script>
, the background will parse it as &#60;script&#62;alert&#40;&#34;1&#34;&#41;&#59;&#60;&#47;script&#62;
and store it in the database, and it will be displayed as the original character when it is displayed on the front end, and the js statement will not be executed.

When the landlord returns to the front end, he finds that if it is displayed in html (str), the original characters can be displayed. If val(str) is returned to the text box, HTML entity characters will not be parsed into normal characters. So we need to write an analytic function. The specifics are also very simple, so I won’t post the code here.

Guess you like

Origin blog.csdn.net/qq_38118138/article/details/118081903