spring利用filter进行xss过滤(包含post请求)以及请求入参日志输出

背景:过滤xss攻击,同时将过滤后的日志输出到指定文件。(指定文件输出请看上篇博文)

前景:利用filter进行xss攻击过滤,需要应对不同请求做不同的过滤处理,若是post请求的json格式数据,需要重写getinputstream方法(因为流读取一次后,下层controller无法再次进行读取。原理可自行百度)

因此需要重写两个wrapper(继承HttpServletRequestWrapper)(针对post的json请求以及其他格式的请求)

在filter中以contentType做类型的区分

未做业务耦合的区分(日志输出与xss过滤耦合到一起),若要区分开功能,单独书写即可

一:重写wrapper

1:contentType为multipart/form-data或application/x-www-form-urlencoded

public class XSSNormalRequestWrapper extends HttpServletRequestWrapper {


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

	@Override
	public String[] getParameterValues(String parameter) {
		String[] values = super.getParameterValues(parameter);
		if (values == null) {
			return null;
		}
		int count = values.length;
		String[] encodedValues = new String[count];
		for (int i = 0; i < count; i++) {
			encodedValues[i] = stripXSS(values[i]);
		}
		return encodedValues;
	}

	@Override
	public String getParameter(String parameter) {
		String value = super.getParameter(parameter);
		return stripXSS(value);
	}

	@Override
	public String getHeader(String name) {
		String value = super.getHeader(name);
		return stripXSS(value);
	}

}

2:contentType为application/json

public class XSSBodyRequestWrapper extends HttpServletRequestWrapper {

    private String body;

    public XSSBodyRequestWrapper(HttpServletRequest request) {
        super(request);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, by
Spring Cloud Gateway可以通过编写自定义的过滤器实现XSS过滤。 首先,我们需要创建一个XSS过滤器类,实现`GlobalFilter`和`Ordered`接口: ```java @Component public class XssGlobalFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); HttpHeaders headers = request.getHeaders(); MediaType contentType = headers.getContentType(); HttpMethod method = request.getMethod(); if (contentType != null && contentType.isCompatibleWith(MediaType.APPLICATION_JSON) && HttpMethod.POST.equals(method)) { return chain.filter(exchange.mutate().request(new XssServerHttpRequest(request)).build()); } return chain.filter(exchange); } @Override public int getOrder() { return -1; } } ``` 这里,我们首先判断请求的Content-Type是否为`application/json`,并且请求方法是否为POST,如果是,则将请求的`ServerHttpRequest`替换为我们自定义的`XssServerHttpRequest`,该类继承自`ServerHttpRequestDecorator`,在该类中对请求体进行XSS过滤,代码如下: ```java public class XssServerHttpRequest extends ServerHttpRequestDecorator { public XssServerHttpRequest(ServerHttpRequest delegate) { super(delegate); } @Override public Flux<DataBuffer> getBody() { Flux<DataBuffer> body = super.getBody(); return body.map(dataBuffer -> { CharBuffer charBuffer = StandardCharsets.UTF_8.decode(dataBuffer.asByteBuffer()); String bodyContent = charBuffer.toString(); // 进行XSS过滤 String filteredBodyContent = Jsoup.clean(bodyContent, Whitelist.none()); byte[] bytes = filteredBodyContent.getBytes(StandardCharsets.UTF_8); DataBuffer buffer = new DefaultDataBufferFactory().wrap(bytes); DataBufferUtils.release(dataBuffer); return buffer; }); } } ``` 在该类中,我们首先将`DataBuffer`转换成`CharBuffer`,再将其转换成字符串,然后使用Jsoup对字符串进行XSS过滤,最后再将过滤后的字符串转换成`DataBuffer`返回。 最后,我们需要将这个过滤器添加到Spring Cloud Gateway的过滤器链中,在配置类中添加: ```java @Configuration public class GatewayConfig { @Bean public XssGlobalFilter xssGlobalFilter() { return new XssGlobalFilter(); } @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() // 添加自定义路由 .route(r -> r.path("/api/**").uri("lb://service-provider")) .build(); } } ``` 这样,当请求Content-Type为`application/json`,并且请求方法为POST时,请求体中的HTML标签就会被过滤掉,从而实现XSS过滤
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值