← 返回题目列表

CSRF 和 CORS 有什么区别?Spring Security 如何防护?

高频 中等 第 5 / 23 题 更新于 2026/07/25
CSRFCORSSpring Security

简化版

CSRF(跨站请求伪造)是一种攻击——利用「浏览器会自动带上目标站点的 Cookie」的特性,诱导已登录用户的浏览器向目标站点发起恶意写请求(如转账),服务端如果只认 Cookie 就会当成用户本人操作。CORS(跨源资源共享)是浏览器的一种安全策略——控制「一个源的脚本能不能读取另一个源的响应」。两者不是一回事:CSRF 是攻击、要防;CORS 是访问控制机制、不是鉴权、也不能替代 CSRF 防护。Spring Security:基于 Cookie/Session 的写请求要开 CSRF token 防护跨域 API 要配明确的 CORS(限定来源/方法/头/凭证)。

详细版

CSRF vs CORS 对比:

维度CSRFCORS
是什么一种攻击浏览器安全策略
关注点浏览器自动带 Cookie → 伪造请求脚本能否跨域读响应
防的方向防伪造写请求管跨域读访问权限
是不是鉴权——不是鉴权,别当访问控制
Spring 防护CSRF TokenCorsConfigurationSource

Spring Security 配置:

@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
        // Cookie/Session 场景:开启 CSRF(默认开启)
        .csrf(csrf -> csrf
            .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
        // 跨域 API:配明确的 CORS
        .cors(cors -> cors.configurationSource(corsSource()));
    return http.build();
}

CorsConfigurationSource corsSource() {
    CorsConfiguration c = new CorsConfiguration();
    c.setAllowedOrigins(List.of("https://app.example.com"));  // 明确来源,不是 *
    c.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
    c.setAllowedHeaders(List.of("Authorization", "Content-Type"));
    c.setAllowCredentials(true);   // 带凭证时,allowedOrigins 不能是 *
    var src = new UrlBasedCorsConfigurationSource();
    src.registerCorsConfiguration("/**", c);
    return src;
}

完整版教学

一、两个问题的出发点完全不同

CSRF 和 CORS 名字都带「跨」,但性质完全不同

  • CSRF 是「攻击类型」:它利用的是浏览器自动携带 Cookie的特性,让用户在不知情下发出恶意请求。它是需要防御的坏东西。
  • CORS 是「浏览器安全策略」:它决定一个源的 JavaScript 能不能读取另一个源的响应。它是浏览器的一种访问控制机制

一个是「防伪造请求」,一个是「管跨域读取权限」——出发点根本不同,不能混为一谈,更不能用一个替代另一个。

维度CSRFCORS
性质攻击方式浏览器安全策略
核心原因浏览器自动带 Cookie浏览器限制跨源脚本读响应
防护目标防伪造写请求管控哪些源能读响应
是否鉴权不是也不是

CSRF 看“请求是不是被伪造”,CORS 看“浏览器脚本能不能读响应”,这两个问题不在同一层。

二、CSRF 为什么危险

经典场景:

  1. 用户登录了银行网站 bank.com,浏览器保存了 bank.com登录 Cookie
  2. 用户没退出,又访问了攻击者的恶意页面 evil.com
  3. evil.com 的页面里藏了一个自动提交的表单/请求,指向 bank.com/transfer?to=攻击者&amount=10000
  4. 浏览器发这个请求时,会自动带上 bank.com 的 Cookie(浏览器对同一域名的请求都自动带 Cookie)。
  5. 如果 bank.com 只认 Cookie(看到有效登录 Cookie 就执行),就会把这个伪造请求当成用户本人的转账操作执行。

危险的根源:浏览器自动带 Cookie + 服务端只凭 Cookie 认定身份。用户「被代表」发起了他不知道的操作。

用户已登录 bank.com
  -> 访问 evil.com
  -> evil.com 诱导浏览器请求 bank.com/transfer
  -> 浏览器自动带 bank.com Cookie
  -> 服务端若只认 Cookie,就可能执行伪造写操作

三、CSRF Token 的原理

CSRF Token 防护的思路:让写操作除了 Cookie,还必须带一个「攻击者拿不到的随机 token」

  • 服务端给合法页面/客户端一个随机的、攻击者猜不到的 CSRF token
  • 写操作(POST/PUT/DELETE)必须带上这个 token,服务端校验 token 才执行。
  • 恶意站点虽然能让浏览器自动带 Cookie 发请求,但它读不到目标站点页面里的 token(受同源策略限制,evil.com 无法读取 bank.com 页面内容),所以构造不出合法的写请求

关键在于:Cookie 是自动带的(攻击者能利用),但 token 需要主动读取页面才能拿到(攻击者拿不到)——用「必须主动获取的凭证」来区分「真实用户」和「伪造请求」。

四、CORS 控制的是什么

CORS 管的是「跨域读响应」:浏览器在跨域请求时,会根据服务端返回的 CORS 响应头Access-Control-Allow-Origin 等)决定要不要把响应交给发起请求的前端脚本

  • 非简单请求(带自定义头、PUT/DELETE 等),浏览器会先发 OPTIONS 预检,检查服务端允许的方法和头。
  • 服务端允许 → 浏览器放行;不允许 → 浏览器拦截响应(请求可能已到达服务端,但脚本读不到响应)。

CORS 配错的两种后果:配太严 → 合法前端调不通(跨域被拦);配太松(如允许所有来源还带凭证)→ 把敏感 API 暴露给不该信任的来源

五、带凭证跨域要格外谨慎

如果要允许跨域请求携带 CookieallowCredentials=true),有一条硬规则

  • allowedOrigins 不能是 *(通配所有来源)——必须明确列出可信的具体域名

原因:如果既允许所有来源、又允许带凭证,那么任何网站都能带着用户的 Cookie 跨域访问你的 API 并读取响应——等于把用户的登录态暴露给全世界。所以带凭证时,来源必须是白名单。CORS 配置应尽量窄,按环境区分开发域名和生产域名(别图省事全放开)。

六、Spring Security 中怎么配

根据认证机制选择 CSRF 策略

  • 浏览器表单 + Session(Cookie)应保留 CSRF 防护(Spring Security 默认开启)。因为 Cookie 会被浏览器自动带,存在 CSRF 风险。
  • 纯 Bearer Token API(JWT 放在 Authorization 头)可以按风险关闭 CSRF。因为 Token 不是浏览器自动携带的(要 JS 主动放进 Authorization 头),攻击者的恶意页面无法自动带上你的 Token,CSRF 风险形态大大降低。但仍要防 XSS 和 Token 泄露(XSS 能偷 Token)。

CORS 应在 Security 链中启用(http.cors(...)),并提供统一的 CorsConfigurationSource,明确配置允许的来源、方法、头、凭证。

七、常见误区与追问

  • 误区:CORS 是认证授权。 CORS 只管浏览器是否把跨域响应交给脚本,允许跨域不代表业务上允许访问。
  • 误区:配置了 CORS 就能防 CSRF。 CORS 解决跨域读响应问题,CSRF 利用的是浏览器自动带 Cookie 发写请求,二者不能互相替代。
  • 误区:关闭 CSRF 一定不安全。 如果是纯 Bearer Token 且 Token 不会被浏览器自动携带,CSRF 风险形态会降低,但仍要防 XSS 和 Token 泄露。
  • 追问:为什么 CSRF Token 能挡住伪造请求? 恶意站点能诱导浏览器带 Cookie 发请求,但读不到目标站点页面里的随机 token。
  • 追问:带凭证 CORS 为什么不能用 * 允许所有来源且允许 Cookie 会让任意站点读取带用户凭证的响应,来源必须收窄到可信白名单。
  • 追问:Postman 不受 CORS 限制说明什么? CORS 是浏览器执行的策略,不是服务端鉴权边界,后端 API 仍必须做认证授权。

面试时要能把威胁模型说清楚:CSRF 风险来自「浏览器自动带凭证」,所以看你的认证是否依赖这种自动携带的凭证。

八、加强记忆

CSRF(跨站请求伪造)是一种攻击——利用浏览器自动带 Cookie,诱导已登录用户的浏览器发伪造写请求(服务端只认 Cookie 就中招);防护用 CSRF Token(写操作必须带攻击者拿不到的随机 token——恶意站能带 Cookie 但读不到目标页面的 token)。CORS(跨源资源共享)是浏览器安全策略——控制脚本能否跨域读响应(靠 Access-Control-Allow-* 响应头 + OPTIONS 预检),不是鉴权、别当访问控制(非浏览器客户端不受它约束)。Spring Security:Cookie/Session 写请求保留 CSRF;纯 Bearer Token API 可关 CSRF(Token 非自动携带,但仍防 XSS)CORS 用 CorsConfigurationSource 配明确来源带凭证(allowCredentials)时 allowedOrigins 不能是 *。核心:CSRF 防伪造写、CORS 管跨域读,威胁模型看认证是否依赖浏览器自动带的凭证