XSS解决处理,表单 + JSON 全覆盖,快速整改

全局自动入参过滤(表单 + JSON 全覆盖,快速整改)

2.1 包装类 XssHttpServletRequestWrapper

复制代码
import org.springframework.web.util.HtmlUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {

    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getParameter(String name) {
        String value = super.getParameter(name);
        return HtmlUtils.htmlEscape(value);
    }

    @Override
    public String[] getParameterValues(String name) {
        String[] values = super.getParameterValues(name);
        if (values == null) return null;
        String[] arr = new String[values.length];
        for (int i = 0; i < values.length; i++) {
            arr[i] = HtmlUtils.htmlEscape(values[i]);
        }
        return arr;
    }
}

过滤器 XssFilter

复制代码
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter(urlPatterns = "/*", filterName = "xssFilter")
public class XssFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        chain.doFilter(new XssHttpServletRequestWrapper((HttpServletRequest) request), response);
    }
}

启动类开启 Servlet 扫描

复制代码
@SpringBootApplication
@ServletComponentScan // 关键:扫描 @WebFilter
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

上面只能处理 form表单、GET参数@RequestBody JSON 参数无效,继续往下配置 Jackson

JSON 全局 XSS 反序列化处理

自定义字符串反序列化器

复制代码
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import java.io.IOException;

public class StringXssDeserializer extends StdScalarDeserializer<String> {
    public StringXssDeserializer() {
        super(String.class);
    }

    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String val = p.getValueAsString();
        return XssUtil.htmlEscape(val);
    }
}

Jackson 全局配置

复制代码
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class JacksonConfig {
    @Bean
    public Jackson2ObjectMapperBuilder objectMapperBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(String.class, new StringXssDeserializer());
        builder.modules(module);
        return builder;
    }
}

到此:表单 + JSON 所有字符串入参自动 HTML 转义,XSS 注入直接失效