SpringCloud gateway 防止XSS漏洞_springcloud项目添加xss防护

        //从请求里获取Post请求体
        String bodyStr = resolveBodyFromRequest(serverHttpRequest);
        // 这种处理方式,必须保证post请求时,原始post表单必须有数据过来,不然会报错
        if (StringUtils.isBlank(bodyStr)) {
            logger.error("请求异常:{} POST请求必须传递参数", serverHttpRequest.getURI().getRawPath());
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.BAD\_REQUEST);
            byte[] bytes = "{\"code\":400,\"msg\":\"post data error\"}".getBytes(StandardCharsets.UTF\_8);
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
            return response.writeWith(Mono.just(buffer));
        }
        //白名单处理(看业务需求)
        boolean containsTarget = WhiteListUtils.richTextUrls.stream().anyMatch(s -> path.contains(s));
        if (containsTarget) {
            //bodyStr = XssCleanRuleUtils.xssRichTextClean(bodyStr);
            bodyStr = XssCleanRuleUtils.xssClean2(bodyStr);
        } else {
            bodyStr = XssCleanRuleUtils.xssClean(bodyStr);
        }

        URI uri = serverHttpRequest.getURI();
        URI newUri = UriComponentsBuilder.fromUri(uri).build(true).toUri();
        ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build();
        DataBuffer bodyDataBuffer = stringBuffer(bodyStr);
        Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);

        // 定义新的消息头
        HttpHeaders headers = new HttpHeaders();
        headers.putAll(exchange.getRequest().getHeaders());


        // 由于修改了传递参数,需要重新设置CONTENT\_LENGTH,长度是字节长度,不是字符串长度
        int length = bodyStr.getBytes().length;
        headers.remove(HttpHeaders.CONTENT\_LENGTH);
        headers.setContentLength(length);

        // 设置CONTENT\_TYPE
        if (StringUtils.isNotBlank(contentType)) {
            headers.set(HttpHeaders.CONTENT\_TYPE, contentType);
        }

        // 由于post的body只能订阅一次,由于上面代码中已经订阅过一次body。所以要再次封装请求到request才行,不然会报错请求已经订阅过
        request = new ServerHttpRequestDecorator(request) {
            @Override
            public HttpHeaders getHeaders() {
                long contentLength = headers.getContentLength();
                HttpHeaders httpHeaders = new HttpHeaders();
                httpHeaders.putAll(super.getHeaders());
                if (contentLength > 0) {
                    httpHeaders.setContentLength(contentLength);
                } else {
                    // this causes a 'HTTP/1.1 411 Length Required' on httpbin.org
                    httpHeaders.set(HttpHeaders.TRANSFER\_ENCODING, "chunked");
                }
                return httpHeaders;
            }

            @Override
            public Flux<DataBuffer> getBody() {
                return bodyFlux;
            }
        };

        //封装request,传给下一级
        request.mutate().header(HttpHeaders.CONTENT\_LENGTH, Integer.toString(bodyStr.length()));
        return chain.filter(exchange.mutate().request(request).build());
    } else {
        return chain.filter(exchange);
    }

}

@Override
public int getOrder() {
    return -90;
}

/\*\*

* 从Flux中获取字符串的方法
* @return 请求体
*/
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) {
//获取请求体
Flux body = serverHttpRequest.getBody();
AtomicReference bodyRef = new AtomicReference<>();
body.subscribe(buffer -> {
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(bu

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、什么是XSS攻击 XSS是一种经常出现在web应用的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制——例如同源策略(same origin policy)。这种类型的漏洞由于被黑客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,黑客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击“,而JavaScript是新型的“ShellCode”。 二、XSS漏洞的危害 (1)网络钓鱼,包括盗取各类用户账号; (2)窃取用户cookies资料,从而获取用户隐私信息,或利用用户身份进一步对网站执行操作; (3)劫持用户(浏览器)会话,从而执行任意操作,例如进行非法转账、强制发表日志、发送电子邮件等; (4)强制弹出广告页面、刷流量等; (5)网页挂马; (6)进行恶意操作,例如任意篡改页面信息、删除文章等; (7)进行大量的客户端攻击,如DDoS攻击; (8)获取客户端信息,例如用户的浏览历史、真实IP、开端口等; (9)控制受害者机器向其他网站发起攻击; (10)结合其他漏洞,如CSRF漏洞,实施进一步作恶; (11)提升用户权限,包括进一步渗透网站; (12)传播跨站脚本蠕虫等; 三、过滤器配置 web.xml配置 XssFilter com.xxx.Filter.XssFilter XssFilter /*
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过滤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值