본문 바로가기
Springboot Study/Springboot Security

CORS(Cross-Origin Resource Sharing, 교차 출처 리소스 공유)

by xogns93 2024. 11. 1.

CORS(Cross-Origin Resource Sharing)는 웹 애플리케이션이 다른 출처의 리소스에 접근할 수 있도록 허용하는 보안 메커니즘입니다. 이 기능은 브라우저와 서버 간의 보안 정책을 설정해, 외부 출처로부터의 요청을 제어할 수 있도록 합니다. CORS 설정은 웹 애플리케이션의 보안을 강화하면서도, 필요한 경우에만 특정 출처에서의 요청을 허용할 수 있게 해줍니다.

1. 기본 CORS 개념

CORS는 동일 출처 정책(SOP, Same-Origin Policy)에 기반을 두고 있으며, 웹 페이지가 로드된 출처(도메인, 프로토콜, 포트)와 다른 출처의 리소스에 접근할 수 없도록 제한하는 보안 장치입니다. CORS를 통해 서버는 외부 출처에서의 요청을 허용할 수 있습니다.

2. CORS 요청 유형

  • Simple Request(단순 요청): 단순 요청은 GET, POST, HEAD 메서드와 몇 가지 기본 헤더(Content-Type, Accept 등)만 사용하는 요청으로, 프리플라이트 요청 없이 바로 서버로 전송됩니다.
  • Preflight Request(프리플라이트 요청): 복잡한 요청(예: PUT, DELETE)이나 커스텀 헤더가 포함된 요청은 서버가 요청을 허용하는지 확인하기 위해 브라우저가 사전에 OPTIONS 메서드로 프리플라이트 요청을 전송합니다.

3. CORS 관련 HTTP 헤더

CORS는 서버가 브라우저에 적절한 응답을 보내기 위해 여러 HTTP 헤더를 사용합니다:

  • Access-Control-Allow-Origin: 허용된 출처를 명시합니다. *로 설정하면 모든 출처에서의 접근을 허용하지만, 보안상 특정 도메인으로 한정하는 것이 권장됩니다.
  • Access-Control-Allow-Methods: 허용된 HTTP 메서드를 지정합니다. 예를 들어, GET, POST, PUT, DELETE와 같이 설정할 수 있습니다.
  • Access-Control-Allow-Headers: 허용된 요청 헤더를 지정합니다. 보안상의 이유로 서버는 필요에 따라 특정 헤더만 허용할 수 있습니다.
  • Access-Control-Allow-Credentials: 쿠키와 같은 자격 증명이 포함된 요청을 허용하려면 이 값을 true로 설정해야 합니다.
  • Access-Control-Max-Age: 프리플라이트 요청의 응답을 캐시하는 시간(초)을 지정하여, 반복되는 프리플라이트 요청을 방지합니다.

4. CORS 설정 예제 (Spring Boot)

Spring Boot에서는 WebMvcConfigurer 인터페이스를 구현해 CORS를 설정할 수 있습니다:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https://trusted.example.com")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("Authorization", "Content-Type")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

5. CORS 설정 시 고려사항

  • 보안: Access-Control-Allow-Origin*로 설정할 경우 모든 출처에서의 접근을 허용하기 때문에 보안이 필요한 애플리케이션에는 적합하지 않습니다. 특정 출처를 명시하여 제한하는 것이 좋습니다.
  • 자격 증명: Access-Control-Allow-Credentials: true를 설정하면 출처를 특정해야 하며, * 설정을 사용할 수 없습니다.
  • 프리플라이트 요청 최적화: 프리플라이트 요청이 반복될 경우 성능에 영향을 줄 수 있으므로, 브라우저가 캐시를 사용할 수 있도록 Access-Control-Max-Age 헤더를 설정하는 것이 좋습니다.

6. CORS 오류와 해결 방법

CORS 설정이 올바르지 않을 경우, 브라우저 콘솔에서 오류 메시지가 표시됩니다. 대표적인 오류는 다음과 같습니다:

  • CORS header ‘Access-Control-Allow-Origin’ missing: 서버가 Access-Control-Allow-Origin 헤더를 포함하지 않았을 때 발생합니다.
  • The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard ‘*’: 자격 증명을 사용했으나 서버에서 출처를 *로 허용한 경우 발생합니다.
  • Preflight response is not successful: 프리플라이트 요청에 대한 응답이 올바르지 않을 때 발생합니다. 이 경우 허용된 메서드, 헤더 등을 점검해야 합니다.

7. CORS와 보안

CORS는 CSRF(Cross-Site Request Forgery)와 같은 공격을 방지하는 데 도움이 됩니다. API 서버에서는 출처 제한과 적절한 메서드 및 헤더 설정을 통해 필요한 요청만 허용하여 보안을 강화할 수 있습니다.

8. CORS 예외 처리

서버에서 특정 경로에 대해 CORS를 예외 처리할 수 있습니다. 예를 들어, @CrossOrigin 애너테이션을 사용해 컨트롤러 수준에서 CORS를 설정하거나 특정 경로에 대해 허용할 수 있습니다:

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExampleController {

    @CrossOrigin(origins = "https://allowed-origin.com")
    @GetMapping("/example")
    public String example() {
        return "CORS-enabled response";
    }
}

요약

CORS는 보안을 위해 동일 출처 정책을 강화하면서도 필요한 경우 외부 출처의 리소스 접근을 허용하기 위한 메커니즘입니다. 서버는 Access-Control-* 헤더를 통해 외부 출처의 요청을 허용할지 여부를 결정하며, 적절한 설정을 통해 보안성과 기능성을 모두 확보할 수 있습니다.

'Springboot Study > Springboot Security' 카테고리의 다른 글

JWT (JSON Web Token)  (0) 2024.11.01
CSRF(Cross-Site Request Forgery)  (0) 2024.10.31
Filter (FilterChain)  (0) 2024.10.31
Spring Security에서 중요한 인터페이스들  (0) 2024.10.30
스레드풀  (0) 2024.10.29