CORS解决方案汇总
字数 967 2025-08-18 17:33:11

CORS跨域资源共享安全配置指南

1. CORS基础概念

1.1 CORS定义

CORS全称"跨域资源共享"(Cross-origin resource sharing),是一种用于绕过SOP(同源策略)来实现跨域资源访问的技术。

1.2 CORS与SOP的关系

  • SOP(同源策略)限制了网页的业务需求,不能使不同域的网页互相访问
  • CORS的出现是为了弥补SOP的不足

1.3 CORS漏洞

攻击者利用CORS技术获取用户敏感数据,导致信息泄露的安全问题。

2. CORS漏洞验证方法

使用curl命令验证CORS配置:

curl -vv -H "Origin: http://hack${你的域名}" http://${你的域名}

示例:

curl -vv -H "Origin: http://hackbaidu.com" http://xxxx.baidu.com

判断标准

  • 如果Access-Control-Allow-Origin返回*http://hackbaidu.com,则存在漏洞
  • 如果未返回Access-Control-Allow-Origin头,则不存在漏洞

3. CORS安全配置方案

3.1 代码层面配置

3.1.1 单个Controller配置(Spring框架)

@CrossOrigin(origins = {"http://localhost:9000", "http://www.baidu.com"})
@RequestMapping("/testCors.do")
public @ResponseBody String CORSTest(HttpServletRequest request, HttpServletResponse response) {
    String map = "no_pass";
    String origin = request.getHeader("Origin");
    
    if(origin != null){
        String safeOrigin = SecurityUtil.getSafeUrl(origin);
        if(safeOrigin != null){
            map = "pass";
            response.setHeader("Access-Control-Allow-Origin", safeOrigin);
            response.setContentType("application/json;charset=UTF-8");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("XDomainRequestAllowed","1");
        } else{
            map = "checked_no_pass";
        }
    } else{
        map = "pass";
    }
    return map;
}

关键点

  • 不允许使用通配符*配置
  • 只设置需要跨域的接口
  • 对origin来源进行严格验证

3.1.2 全局Controller配置

方式一:Java Bean注解配置

@Configuration
public class MyConfiguration {
    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://domain1.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }
}

方式二:XML配置

<!-- support cors-->
<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,xsrf-token</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>www.test.com</url-pattern>
</filter-mapping>

3.2 Nginx配置方案

set $cors_origin "";
if ($http_origin ~* "^http://127.0.0.1$") {
    set $cors_origin $http_origin;
}
if ($http_origin ~* "^http://localhost$") {
    set $cors_origin $http_origin;
}
add_header Access-Control-Allow-Origin $cors_origin;

location / {
    if ($request_method = 'OPTIONS') {
        add_header Access-Control-Allow-Origin $cors_origin;
        add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
        return 204;
    }
}

注意事项

  • 不要同时在Nginx和后端代码中配置CORS,会导致跨域配置失败
  • 浏览器会收到两个Access-Control-Allow-Origin头,导致错误

3.3 Kubernetes Ingress配置(YAML方案)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/configuration-snippet: |
      set $allow_cors "";
      if ($http_origin ~ "^https?://([a-zA-Z0-9.-]+\.)?test\.com(:\d+)?$") {
        set $allow_cors "true";
      }
      more_set_headers 'Access-Control-Allow-Origin: $allow_cors';      
spec:
  rules:
    - host: your.host.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: your-service-name
                port:
                  name: http

4. 跨域测试方案

在浏览器开发者控制台执行以下JavaScript代码测试:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.xxx.com/api/action');
xhr.send(null);
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
}

结果分析

  1. 请求超时:网络不通或地址无效
  2. 正常返回:支持跨域
  3. 返回错误:不支持跨域

5. 安全配置最佳实践

  1. 白名单原则

    • 只设置企业内部需要的域名
    • 不允许使用通配符*配置
    • 具体域名不使用任何通配符(如*.test.com一级域名不能被统配)
  2. 配置层级选择

    • 只在一个地方配置CORS(Nginx或后端代码)
    • 避免多层配置导致冲突
  3. 敏感接口保护

    • CORS和JSONP接口不开放给外部调用
    • 白名单内只设置企业内部域名
  4. 黑白盒结合测试

    • 代码扫描可能无法发现Nginx层的配置问题
    • 必须进行黑盒测试验证实际效果
CORS跨域资源共享安全配置指南 1. CORS基础概念 1.1 CORS定义 CORS全称"跨域资源共享"(Cross-origin resource sharing),是一种用于绕过SOP(同源策略)来实现跨域资源访问的技术。 1.2 CORS与SOP的关系 SOP(同源策略)限制了网页的业务需求,不能使不同域的网页互相访问 CORS的出现是为了弥补SOP的不足 1.3 CORS漏洞 攻击者利用CORS技术获取用户敏感数据,导致信息泄露的安全问题。 2. CORS漏洞验证方法 使用curl命令验证CORS配置: 示例: 判断标准 : 如果 Access-Control-Allow-Origin 返回 * 或 http://hackbaidu.com ,则存在漏洞 如果未返回 Access-Control-Allow-Origin 头,则不存在漏洞 3. CORS安全配置方案 3.1 代码层面配置 3.1.1 单个Controller配置(Spring框架) 关键点 : 不允许使用通配符 * 配置 只设置需要跨域的接口 对origin来源进行严格验证 3.1.2 全局Controller配置 方式一:Java Bean注解配置 方式二:XML配置 3.2 Nginx配置方案 注意事项 : 不要同时在Nginx和后端代码中配置CORS,会导致跨域配置失败 浏览器会收到两个 Access-Control-Allow-Origin 头,导致错误 3.3 Kubernetes Ingress配置(YAML方案) 4. 跨域测试方案 在浏览器开发者控制台执行以下JavaScript代码测试: 结果分析 : 请求超时:网络不通或地址无效 正常返回:支持跨域 返回错误:不支持跨域 5. 安全配置最佳实践 白名单原则 : 只设置企业内部需要的域名 不允许使用通配符 * 配置 具体域名不使用任何通配符(如 *.test.com 一级域名不能被统配) 配置层级选择 : 只在一个地方配置CORS(Nginx或后端代码) 避免多层配置导致冲突 敏感接口保护 : CORS和JSONP接口不开放给外部调用 白名单内只设置企业内部域名 黑白盒结合测试 : 代码扫描可能无法发现Nginx层的配置问题 必须进行黑盒测试验证实际效果