하나씩 알아가기

CORS에 대해서 알아보자 본문

CORS에 대해서 알아보자

clearwater 2021. 1. 25. 15:50
728x90
반응형

틀린 부분이 있을 경우, 지적해 주시면 감사하겠습니다.

 

CORS는 Cross-Origin Resource Sharing의 약자로 교차 출처 자원 공유를 의미합니다.

HTTP헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에게 알려주는 메커니즘입니다. 웹 애플리케이션은 리소스가 자신의 출처와 다를 때 교차 출처 HTTP 요청을 실행합니다.

 

※출처(Origin)를 구분하는 방법인데 프로토콜과 호스트, 그리고 포트번호가 같으면 동일 출처로 봅니다. 이 셋 중 하나라도 다르면 동일 출처 정책(SOP)이 적용되서 요청에 실패합니다.

 

잠깐 동일 출처 정책에 대해 짚고 넘어가겠습니다. 사실 CORS는 이것으로부터 시작된 이야기입니다.

SOP

Same-Origin Policy(동일 출처 정책)은 웹이 개방되어 있기 때문에 나쁜 리소스에 의한 악의적 공격 등이 있을 수 있습니다. 그래서 같은 출처인 경우에만 리소스를 받을 수 있게 해준 정책을 말합니다.

그런데 동일 출처가 아니더라도 다른 정보들을 보여주고 싶을 경우가 있을 수 있으므로 예외 조항을 만들어 놓았습니다. 그 중 하나가 CORS 정책을 지킨 요청을 허용해 주는 조항입니다.

 

CORS와 SOP가 나오게 된 이유는 XSS 같은 보안 취약점 공격이 요청으로 들어올 경우 대응하기 어렵기 때문입니다.

 

※ XSS(사이트 간 스크립팅, cross-site scripting): 웹 상에서 가장 기초적인 공격 방법의 일종으로, 악의적인 사용자가 공격하려는 사이트에 스크립트를 넣는 기법을 말합니다. 공격에 성공하면 사이트에 접속한 사용자는 삽입된 코드를 실행하게 되며, 보통 의도치 않은 행동을 수행시키거나 쿠키나 세션 등의 민감한 정보를 탈취합니다.

 

CORS에 대해 이어서 정리하겠습니다.

클라이언트가 서버에 HTTP 요청을 보낼 때 HTTP 헤더의 Origin 속성에 자동으로 값이 할당됩니다.

도메인에서 다른 출처의 자원을 사용하기 위해 ajax 요청을 했다고 하면 SOP 정책 때문에 에러가 발생합니다. 그래서 이를 해결하려면 서버의 HTTP 응답 헤더에 Access-Control-Allow-Origin 도메인을 명시해야합니다. 그러면 브라우저가 동일출처라고 인식하기 때문에 에러를 해결할 수 있습니다.

 

세 가지 시나리오

1) Preflight Request(예비 요청)

OPTIONS 메소드로 예비요청을 보내고 본 요청을 보냅니다.

Origin에 대한 정보 뿐만 아니라 자신이 예비 요청 이후에 보낼 본 요청에 대한 다른 정보들도 같이 포함되어 있습니다(예를 들어 Access-Control-Request-Headers, Access-Control-Request-Method 등).

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

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

 

2) Simple Request

본 요청에서 예비 요청에서 했던 행동을 모두 합니다. 본 요청에서 Origin을 담게 되고 응답에서 Access-Control-Allow-Origin과 다르게 되면 브라우저가 CORS 정책을 위반했다고 에러를 발생시킵니다.

제약 사항

  • 요청의 메소드는 GET, HEAD, POST 중 하나여야 한다.
  • Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width를 제외한 헤더를 사용하면 안된다
  • 만약 Content-type을 사용하는 경우에는 application/x-www-form-urlencoded, multipart/form-data, text/plain만 허용된다(이 세 개 중에 application-json이 없어서 우리는 REST-API를 많이 쓰기 때문에 확인이 어렵습니다)

3) Credentialed Request

옵션 값 설명
same-origin(기본값) 같은 출처 간 요청에만 인증 정보를 담는다
include 모든 요청에 인증정보를 담는다
omit 모든 요청에 인증 정보를 담지 않는다

fetch안에다 {credentials: include}를 같이 넘겨주면 브라우저에서 쿠키를 같이 넘겨주고 서버에서 인증이 됐다고 하면 제대로된 응답을 내려주게 되고 브라우저가 CORS 정책의 위반 유무를 가리게 됩니다.

 

 

정리

모든 출처의 자원을 받는 것은 위험하기 때문에 원하는 출처의 자원만 받는 정책이라고 말할 수 있습니다. 서버 사이드에서는 프론트 개발자를 위해 응답 헤더에 올바른 Access-Control-Allow-Origin이 내려올 수 있도록 세팅해 줘야합니다. 클라이언트 사이드에서는 Webpack Dev Server로 리버스 프록싱 하여 우회가 가능한데 로컬 환경에서만 가능합니다. 그래서 서버 개발자에게 도움을 요청하는 것이 좋은 방법이라할 수 있습니다.

 

 

참고 및 출처

www.youtube.com/watch?v=7iGIfcEsc2g

 

728x90
반응형