웹 브라우저는 언제든지 JS 를 호출할 수 있고, 프로그램을 설치해야 무엇인가를 실행할 수 있는 프로세스와 달리 JS 는 꼭 굳이 자바스크립트 파일이 없더라도
<script>태그 안에 몇 문장만 작성하면 바로 실행할 수 있다. 어떤 검증도 없이 바로 자바스크립트를 수행할 수 있기 때문에 웹 브라우저는 많은 해커들로부터 공격의 대상이 되기 쉽고 어떻게든 악의적인 JS 를 수행하게만 하면 된다.물론 치명적인 문제를 발생시키는 JS 문법은 없지만 JS 통해 외부 API 에 요청을 보낼 수 있게 되어서, 유저가 의도적으로 API 호출한것이 아니라 악의적으로 심어진 JS 실행을 통해 API 가 호출될 수 있다.
로그인 정보 혹은 세션키들이 모두 Cookie 에 저장되어있다면 단순히 API 를 호출함으로 인해 해당 Cookie 값들이 모두 헤더에 담겨 요청이 전송되게 되고, 유저는 자신이 알지도 못하는 사이에 Cookie 에 담긴 로그인 정보를 통해 외부 API 가 자유롭게 인증정보에 대한 요구나 문제 없이 호출되게된다.
SOP는 웹 브라우저의 기본 보안 정책으로, 서로 다른 출처(Origin) 간의 상호작용을 제한합니다. 이 정책은 웹 애플리케이션이 악의적인 코드로 인해 보안 문제를 일으키지 않도록 보호하기 위해 설계되었습니다.
동일한 Origin에서 로드된 리소스만이 상호작용할 수 있습니다.
외부 Origin에서 온 스크립트나 리소스가 민감한 데이터에 접근하지 못하도록 제한합니다.
예시: Cross-Origin 발생!
A 사이트(https://a.com)의 JavaScript가 B 사이트(https://b.com)의 데이터를 직접 요청하지 못하도록 차단.
SOP는 보안을 강화하기 위해 엄격한 정책을 적용하지만, 일부 리소스는 예외적으로 허용됩니다
이미지(<img> 태그)
스타일시트(<link> 태그)
외부 리소스 포함(<iframe> 태그)
폼(<form> 태그) -> FORM 동기 -> 호출 됨
스크립트(<script> 태그) -> AJAX 비동기 -> 호출안됨
SOP는 Cross-Origin 요청(예: AJAX 요청) 자체를 막아버리기 때문에, 다양한 API 호출이 필수인 현대 웹 애플리케이션에서 불편함을 초래합니다.
이를 해결하기 위해 CORS를 도입하여, 서버가 명시적으로 허용한 경우에만 Cross-Origin 요청을 허용하도록 했습니다.
브라우저에서 요청
서버에서 응답:
브라우저에서 검증:
CORS 요청은 Simple Request와 Preflight Request로 나뉩니다.
특징: 브라우저가 서버에 요청시 사전 검증 없이 바로 요청을 전송.
요청과 응답의 CORS 정책을 요청 후 응답에서만 검증.
조건: 요청이 Simple Request로 간주되기 위해 다음 조건을 충족해야함.
과정:
특징: 요청 전에 브라우저가 OPTIONS 메서드로 "사전 요청(Preflight Reques)"을 보내서 서버가 해당 요청을 허용하는지 확인.
조건:
Authorization, X-Custom-Header 같은 커스텀 헤더.과정:
Access-Control-Request-Method, Access-Control-Request-HeadersAccess-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers허용할 Origin 지정:
Access-Control-Allow-Origin: https://example.com
Origin: https://example.comAccess-Control-Allow-Origin: https://example.com허용할 HTTP 메서드 지정:
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Request-Method: POSTAccess-Control-Allow-Methods: GET, POST허용할 헤더 지정:
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Request-Headers: Content-Type, AuthorizationAccess-Control-Allow-Headers: Content-Type, Authorization인증 정보 포함 여부:
Access-Control-Allow-Credentials: true
CORS는 기본적으로 쿠키나 인증 정보를 포함하지 않습니다. 하지만 credentials 옵션을 사용해 인증 정보를 포함할 수 있습니다.
브라우저 측 설정:
서버 측 설정:
제약사항:
allowOriginPatterns 예시
http.cors().configurationSource(request -> {
CorsConfiguration config = new CorsConfiguration();
// 특정 도메인 패턴 허용
config.setAllowedOriginPatterns(List.of("https://*.example.com"));
// 허용할 HTTP 메서드 지정
config.setAllowedMethods(List.of("GET", "POST"));
// 인증 정보를 허용 (쿠키, Authorization 헤더 등)
config.setAllowCredentials(true);
// 허용할 헤더 설정 (필요 시 추가)
config.setAllowedHeaders(List.of("*"));
return config;
});
- 와일드카드(*)를 사용할 수 있지만, 도메인 이후의 패스까지 세밀하게 통제할 수 있습니다.
- 예를 들어, https://*.example.com은 https://sub.example.com을 허용하지만, https://another.com은 허용하지 않습니다.