This is the third day of my participation in the November Gwen Challenge. Check out the details: the last Gwen Challenge 2021

The target

Spring Boot Filter is used to intercept parameters, and Jsoup is used to Filter XSS in parameters

tool

  • Spring Boot 2.0
  • Jsoup (optional)

Realize the principle of

The Spring Boot Filter intercepts the front-end parameters and filters them. .

Basically, there are two functions: parameter blocking and script filtering.

Parameters to intercept

To filter XSS, you first need to be able to intercept front-end parameters.

Write a first Filter:

import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class XSSEscapeFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {/ / will have XssHttpServletRequestWrapper code behind. This class is his own definition of chain. DoFilter (new XssHttpServletRequestWrapper ((it) request), response); }}Copy the code

The Filter can intercept to the request, but, if you want to modify the parameters will need to redefine HttpServletRequestWrapper, only with a custom HttpServletRequestWrapper can modify parameters.

The following definitions XssHttpServletRequestWrapper:

import org.apache.commons.lang3.StringUtils; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.safety.Whitelist; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.*; import java.util.HashMap; import java.util.Iterator; import java.util.Map; / * * * * Create by zdRan XSS filtering on 2018/5/8 @ author [email protected] * * * / public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { private HttpServletRequest orgRequest = null; public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); orgRequest = request; } @override public String getParameter(String name) {return name; } @override public Map getParameterMap() {return super.getparameterMap (); } @Override public String[] getParameterValues(String name) { String[] arr = super.getParameterValues(name); Return arr; } @override public String getHeader(String name) {return super.getheader (name); } public HttpServletRequest getOrgRequest() {return orgRequest; } /** * return */ public static HttpServletRequest getOrgRequest(HttpServletRequest req) {if (req instanceof XssHttpServletRequestWrapper) { return ((XssHttpServletRequestWrapper) req).getOrgRequest(); } return req; }Copy the code

This allows you to modify the parameters, but the current situation does not allow you to handle POST requests or RequestBody annotations.

When using the RequestBody annotation, you will notice that none of the methods overwritten are left, indicating that we have not overwritten the whole method.

A bit of digging found that the RequestBody annotation reads the parameter using getInputStream().

Let’s rewrite this method:

@Override public ServletInputStream getInputStream() throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(orgRequest.getInputStream())); String line = br.readLine(); String result = ""; if (line ! = null) {/ / to deal with parameter} return new WrappedServletInputStream (new ByteArrayInputStream (result) getBytes ())); }Copy the code

Then start the Filter

import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.servlet.DispatcherType; /** * Create by zdRan on 2018/5/8 * * @author [email protected] */ @Configuration public class XssFilterConfiguration { / * * * XSS filter interceptor * / @ Bean public FilterRegistrationBean xssFilterRegistrationBean () {FilterRegistrationBean initXssFilterBean = new FilterRegistrationBean(); initXssFilterBean.setFilter(new XSSEscapeFilter()); initXssFilterBean.setOrder(1); initXssFilterBean.setEnabled(true); initXssFilterBean.addUrlPatterns("/*"); initXssFilterBean.setDispatcherTypes(DispatcherType.REQUEST); return initXssFilterBean; }}Copy the code

At this point, the parameters are basically intercepted, and you can define your own rules for modifying the parameters. XSS can also be filtered using JSOUP

Script filtering

Use JSOUP to filter labels in parameters to add dependencies

<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.11.3</version>Copy the code

All right. That’s the end of it, but there’s just one small problem.

Using Jsoup allows you to filter out all HTML tags, but there is a problem, for example

Parameters are: {” name “:” < HTML “, “passwd” : “12345”}, the filtered result is: {” name “:”

Because the end of the < HTML > tag is not found, all subsequent arguments are filtered out.

This will cause an exception when the controller gets parameters.

But even if the HTML tag is returned to the front end, the browser can’t parse it because the tag is wrong. If you really need to filter this parameter.

You can try filtering special characters directly.