第二十二周_T-CORS 跨域资源共享

47 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 10 天,点击查看活动详情 CORS 跨域资源共享

背景

  1. 以前碰到前端说跨域都是直接解决,一般项目中是不会存在新开发接口跨域的,因为都是全局配置。
    当然,这只是一般情况。我碰到一个开发老项目的,接口给到前端开发,直接跨域。一查才发现没有全局配置,以前的接口怎么解决这个问题的呢?每个 Controller 类上加注解 @CrossOrigin ……
  2. 最近项目进行渗透扫描:也出现了这个漏洞,如下
    漏洞名称:CORS跨域资源共享
    漏洞等级:低风险
    漏洞危害:
    CORS配置错误,Origin字段校验不严格
    漏洞地址:xxx
    修复建议:对Origin字段进行严格检验,正确配置CORS

基于上面,觉得有必要详细学习下

简介

CORS 是一个W3C标准,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。
现在我们的项目都是前后端分离,所以只要你不配置,必定跨域。
那么什么是同源呢?
同源指 "三个" 相同:「协议」、「域名」、「端口」
CORS 需要浏览器和服务器同时支持,目前,所有的浏览器都支持该功能,IE不能低于IE10。不过微软将于 2023年2月14日 关闭 IE 浏览器,IE 成为历史,取而代之的是 Edge 浏览器。
整个 CORS 通信过程都是浏览器自动完成,一旦浏览器发现 AJAX 请求跨源,就会自动条件一些附加的信息,有时还会多一次附加的请求,但用户不会有感觉。
因此实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨源通信。

简单请求 VS 非简单请求

参考我以前写的这篇文章:juejin.cn/post/718383…

实现 CORS

一般来说:下面的实现都是一把梭哈

具体体现在:下面三个返回头信息都是 * ,表示什么都通过。所以项目才会有上面的漏洞

response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Headers", "*");

下面限制了请求源:就跟设置白名单一样。

还限制了请求方式只能是 GET、POST 两种。

 @Bean
    public CorsFilter corsFilter()
    {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        // 设置访问源地址:白名单
        String[] strs = ipList.split(",");
        Arrays.stream(strs).forEach(t->{
            config.addAllowedOriginPattern(t);
        });
        // 设置访问源请求头
        config.addAllowedHeader("*");
        // 设置访问源请求方法
        config.addAllowedMethod(HttpMethod.GET);
        config.addAllowedMethod(HttpMethod.POST);
        // 有效期 1800秒
        config.setMaxAge(1800L);
        // 添加映射路径,拦截一切请求
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        // 返回新的CorsFilter
        return new CorsFilter(source);
    }

其他解决方案

JSONP

只能发起 GET 请求,局限性太大。

ng

nginx 反向代理,利用nginx反向代理把跨域为不跨域,支持各种请求方式。但是需要在nginx进行额外配置,语义不清晰