본문 바로가기
공부

CORS란?

by eunyoung 2023. 5. 28.

CORS에 대해서 한번 정리해보고자 한다.

프로젝트를 진행하면서, 웹 프론트엔드 작업을 하였는데 이때도 CORS에 대해서 많이 접하였고 또 기술 면접에서도 이에 대해서 질문을 많이 받았다.

 

한번 정리하는 김에 제대로 정리하고 싶어서 CORS에 대해서 포스팅한다.

 

 

CORS란?


CORS는 Cross-Origin Resources Sharing으로 교차 출처 자원 공유 원칙이다.

 

웹 브라우저에서는 교차 출처(Cross-Origin)의 HTTP 요청이 제한된다.

즉, 이를 허용하려면 서버에서 HTTP 헤더를 통해서 허용 정보를 보내주어야 한다.

 

즉, CORS는 

추가 HTTP 헤더를 사용하여, 브라우저에서 교차 출처(Cross-Origin) HTTP 요청을 안전하게 할 수 있도록 하는 체제이다.

 

(한 출처에서 실행중인 웹 어플리케이션이 다른 출처의 선택한 자원에 접근할 수 있도록 권한을 부여하도록 브라우저에 알려주는 체제이다)

 

이미지 출처 : https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

 

출처(Origin)이란?

URL에 Protocol(ex.https) + Host(ex. eunyy23-dev.tistory.com) + Port(ex.443)를 말한다.

웹 브라우저의 개발자 도구의 콘솔 창에 location.origin을 실행하면 출처를 확인할 수 있다.

 

(ex) 

 

 

서버에서 응답 메세지를 보낼때 응답 헤더에 올바른 Access-Control-Allow-Origin이 있을 수 있도록 해야한다.

Request에 Origin이라는 헤더가 있고, Response에 Access-Control-Allow-Origin을 비교해서 같으면 같은 출처라고 브라우저는 인식한다.

이때, 서버 영역이 아닌 브라우저 영역이기 때문에 서버는 200대의 성공 코드를 반환한다.

 

 

 

CORS가 필요한 이유는?


브라우저가 SOP(Same Origin Policy - 동일 출처 정책)를 지켜서 다른 출처의 리소스 접근을 금지하기 때문에 필요하다.

 

SOP(Same Origin Policy - 동일 출처 정책)이란?

다른 출처의 리소스를 사용하는 것에 제한하는 보안 방식

 

 

 

그럼 SOP(Same Origin Policy -  동일 출처 정책)이 필요한 이유는?


CORS가 필요한 이유가 웹 브라우저가 SOP(동일 출처 정책)을 지켜서라고 하는데 SOP(동일 출처 정책)을 지켜야 하는 이유가 궁금해졌다. 

 

SOP의 장점으로는 

SOP(동일 출처 정책)을 지키면 외부 리소스를 가져오지 못해 불편하지만, XSS나 XSRF 등의 보안 취약점을 노린 공격을 방어할 수 있다고 한다.

 

하지만 현실적으로 동일 출처가 아닌 외부 리소스를 참고하는 것은 필요하기 때문에 외부 리소스를 사용하기 위한 SOP의 에외 조항이 필요하고 이것이 바로 CORS이다.

 

XSS(Cross-Site Scripting)이란?

가장 널리 알려진 웹 보안 취약점 중 하나임.

악의적인 사용자가 공격하려는 사이트에 악성 스크립트를 삽입할 수 있는 보안 취약점이다.

대표적인 공격 방식으로는 Stored XSS, Reflected XSS, DOM Based XSS가 있다.

 

 

XSRF(Cross-Site Request Forgery)이란?

사이트 간 요청 위조이다.

웹 애플리케이션의 취약점 중 하나로 사용자가 자신의 의지와 무관하게 공격자가 의도한 행동을 해서 특정 웹 페이지를 보안에 취약하게 한다거나 수정,삭제 등의 작업을 하게 만드는 공격 방법이다.

(ex) 공격자는 자금 송금이나 로그인 정보 변경 등 원하는 요청을 위조한 후, 이메일이나 웹 사이트에 요청이 삽입된 하이퍼링크를 심어놓고, 사용자가 해당 하이퍼링크를 클릭하면 요청이 자동을 전송되도록 함.

 

 

결과적으로, CORS 자체는 서버가 아닌 브라우저에 걸려있는 정책이다.

서버는 단지 헤더를 통해서 Origin을 보내줄 뿐이다.

결과적으로는 클라이언트가 XSS나 CSRF 등으로 의도하지 않는 요청이 날라가지 않도록 클라이언트를 보호하기 위한 것이다.

 

 

 

CORS의 동작 방식은?


프리플라이트 요청(Preflight Request), 단순 요청(Simple Request), 인증정보 포함 요청(Credentialed Request)이 있다.

 

1. 프리플라이트 요청(Preflight Request)이란?

OPTIONS 메서드로 예비 요청을 보내고 이후 본 요청을 보내는 방식이다.

요청에 Origin과 응답의 Access-Control-Allow-Origin을 브라우저가 비교해서 출처를 판단하여 다르면 에러를 발생시키고 접근할 수 있는 출처라면 본 요청을 보내서 요청을 처리하도록 하는 방식이다.

Preflight Request가 거부되면 실제 요청(Actual Request)을 보내지는 않는다.

Preflight Request와 Preflight Response에서 서버는 200대의 성공 코드를 반환한다.

 

전체 프로세스는 아래 그림과 같다.

 

이미지 출처 : https://developer.mozilla.org/ko/docs/Web/HTTP/CORS



[Preflight Request 형식]

Origin : 요청 출처

Access-Control-Request-Method : 실제 요청의 메서드

Access-Control-Request-Headers : 실제 요청의 추가 헤더

 

[Preflight Response 형식]

Access-Control-Allow-Origin : 서버 측 허가 출처

Access-Control-Allow-Methods : 서버 측 허가 메서드

Access-Control-Allow-Headers : 서버 측 허가 헤더

Access-Control-Max-Age : Preflght 응답 캐시 시간

 

 

 

2. 단순 요청(Simple Request)이란?

프리플라이트 요청과 다른 점은 예비 요청을 보내지 않고, 본 요청만 한번 보내는 방식이다 -> 프리플라이트 예비 요청에서 한 것을 단순 요청의 본 요청에서 다하는 방식이다.

 

이미지 출처 : https://minzoovv.dev/HTTP/cors/

 

[Simple Request를 보내기 위해서는 다음 조건을 만족하여야 한다]

1. GET, POST, HEAD 메서드 이어야 한다.

2. Content-Type은 application/x-www-form-urlencoded, multipart/form-data, text/plain이어야 한다.

3. 헤더는 Accept, Accept-Language, Content-Language, Content-Type 만 허용된다.

 

 

그럼 프리플라이트 요청에서 본 요청을 한번만 보내지 않고, 예비 요청을 보내는 이유는 무엇일까?

 

서버 중에서 CORS 설정이 제대로 되어 있지 않는 서버를 위해서이다.

프리플라이트 request가 CORS를 모르는 서버에게 가게 되면 서버가 제대로 된 응답을 보내지 못하게 되고 그렇게 되면 브라우저가 실제 본 요청을 보내지 않게 된다. 따라서 CORS를 모르는 서버를 위해서 예비 요청이 필요하다.

 

 

3. 인증정보 포함 요청(Credentialed Request)이란?

인증 관련 헤더를 포함할때 사용하는 요청 방식이다.

 

이미지 출처 : https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

 

[Credentialed Request를 보내기 위해서는 다음 조건을 만족하여야 한다.]

1. Access-Control-Allow-Origin에서는 *을 사용할 수 없고, 명시적인 URL이어야 한다.

2. 응답 헤더에는 반드시 Access-Control-Allow-Credentails: true가 존재해야 한다.

 

 

 

 

CORS를 위반하는 경우 해결하는 방법은?


1. Access-Control-Allow-Origin 세팅하기

프론트 개발자를 위해서 HTTP 응답 메세지의 응답 헤더에 Access-Control-Allow-Origin이 내려올 수 있도록

설정해주어야 한다.

 

 

 

2. 프록시 서버를 사용하기

프록싱을 통해서 CORS 정책을 우회할 수 있다.

 

 

 

스프링 부트에서 설정값으로 설정하기

@CrossOrigin을 붙여서 설정값으로 CORS를 설정할 수 있다.

 

 

 

 

 

 

참고


'공부' 카테고리의 다른 글

데이터베이스 인덱스 1 - 인덱스 개념, 종류 등  (0) 2023.05.31
웹 브라우저에서 www.google.com을 입력했을때  (0) 2023.05.28
자바의 GC  (2) 2023.05.08
Spring AOP란?  (0) 2023.05.02
데이터베이스 - 인덱스  (0) 2023.04.19