개발/Spring

Spring Security의 CORS와 CSRF 개념 정리

피터JK 2025. 1. 29. 14:51
728x90

 

Spring Security에서는 보안 강화를 위해 CORS (Cross-Origin Resource Sharing)CSRF (Cross-Site Request Forgery) 정책을 제공합니다. 이를 이해하면 보안 정책을 적절히 설정하고, 필요한 경우 이를 해제하여 애플리케이션의 정상적인 동작을 보장할 수 있습니다.


1. CORS (Cross-Origin Resource Sharing)

🧐 CORS란?

  • 서로 다른 도메인(Origin)에서 리소스를 공유할 때 발생하는 보안 정책
  • 기본적으로 브라우저는 **동일 출처 정책(Same-Origin Policy, SOP)**을 적용하여, 다른 도메인의 요청을 차단함.
  • CORS를 설정하면 특정 도메인에서의 요청을 허용할 수 있음.

🎯 CORS 문제 발생 예시

fetch("https://api.example.com/data")
  .then(response => response.json())
  .then(data => console.log(data));

위 코드를 http://localhost:3000에서 실행하면, https://api.example.com이 다른 도메인이므로 브라우저는 요청을 차단함.

✅ Spring Security에서 CORS 설정 방법

Spring Security를 적용하면 기본적으로 CORS 요청이 차단되므로, 허용하려면 설정이 필요함.

🔹 Spring Security 5.x 이후 설정 (SecurityFilterChain)

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .cors(cors -> cors.configurationSource(corsConfigurationSource())) // CORS 설정 적용
            .csrf(AbstractHttpConfigurer::disable); // CSRF 보호 해제 (API 사용 시 추천)

        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000")); // 허용할 도메인 지정
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE")); // 허용할 HTTP 메서드 지정
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type")); // 허용할 헤더 지정
        configuration.setAllowCredentials(true); // 인증 정보 포함 허용

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

2. CSRF (Cross-Site Request Forgery)

🧐 CSRF란?

  • 사용자가 로그인된 상태에서 악의적인 웹사이트에서 인증된 요청을 조작하는 공격 방식
  • CSRF 공격을 방지하려면 요청이 실제 사용자가 의도한 것인지 확인해야 함.

🎯 CSRF 공격 예시

  1. 사용자가 https://bank.com에 로그인하여 세션이 유지됨.
  2. 공격자가 https://evil.com에 CSRF 스크립트를 배포.
  3. 사용자가 https://evil.com에 접속하면, 다음과 같은 요청이 자동으로 실행됨.
    <img src="https://bank.com/transfer?amount=10000&to=attacker" />
  4. 사용자의 인증 정보가 이미 bank.com에 로그인된 상태라면 요청이 성공함.

✅ Spring Security에서 CSRF 설정

Spring Security는 기본적으로 CSRF 보호를 활성화함. 하지만 API 서버의 경우 보통 이를 해제해야 함.

🔹 CSRF 기본 설정 (보호 활성화)

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(AbstractHttpConfigurer::disable) // CSRF 보호 비활성화 (API 서버의 경우)
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            .formLogin(Customizer.withDefaults()); // 기본 로그인 설정
        
        return http.build();
    }
}

🔹 CSRF 보호 유지하면서 REST API 사용 (CSRF Token 설정)

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())) // CSRF 토큰 쿠키 저장
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            .formLogin(Customizer.withDefaults());

        return http.build();
    }
}
  • CookieCsrfTokenRepository.withHttpOnlyFalse()를 사용하면 CSRF 토큰을 쿠키에 저장하여 클라이언트에서 사용할 수 있음.

🔥 결론

항목 설명 기본 설정

CORS 서로 다른 출처 간 요청 허용 설정 차단됨 (설정 필요)
CSRF 인증된 사용자의 요청이 정상적인지 검증 활성화됨
  • CORS는 백엔드가 API 서버일 경우 허용 설정을 해야 함.
  • CSRF는 웹 애플리케이션에서는 유지, REST API 서버에서는 비활성화하는 것이 일반적.

💡 API 서버에서 CORS를 허용하려면 cors().configurationSource()를 설정해야 하며,
💡 CSRF 보호가 필요 없으면 csrf(AbstractHttpConfigurer::disable)을 설정해야 함.

 

728x90