开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 10 天,点击查看活动详情 CORS 跨域资源共享
背景
- 以前碰到前端说跨域都是直接解决,一般项目中是不会存在新开发接口跨域的,因为都是全局配置。
当然,这只是一般情况。我碰到一个开发老项目的,接口给到前端开发,直接跨域。一查才发现没有全局配置,以前的接口怎么解决这个问题的呢?每个 Controller 类上加注解 @CrossOrigin …… - 最近项目进行渗透扫描:也出现了这个漏洞,如下
漏洞名称: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进行额外配置,语义不清晰