CORS(Cross-Origin Resource Sharing)

손연주·2021년 7월 4일
0
post-thumbnail

CORS에 대한 기본적인 이해

  • 웹 브라우저에서 도메인이 다른 서버끼리 서로 요청을 주고 받을 수 있게끔 해주는 것
  • 악성서버를 걸러주는 보안정책으로 하나의 브라우저에서 두 개 이상의 서버와 연결되는 것

브라우저 보안 정책인 CORS교차(다른) 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 서로 다른 오리진 간의 리소스를 공유하는 것이다. 웹 서버, 데이터베이스를 통해서 브라우저의 앱(웹 어플리케이션)의 사용자를 보호하기 위한 브라우저의 보안 장치이다.

한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행한다.

보안 상의 이유로 XMLHttpRequest와 Fetch API는 동일 출처 정책을 따른다. 즉, 이 API를 사용하는 웹 애플리케이션은 자신의 출처와 동일한 리소스만 불러올 수 있으며, 다른 출처의 리소스를 불러오려면 그 출처에서 올바른 CORS 헤더를 포함한 응답을 반환해야 한다.

출처(Origin)란?

서버의 위치를 의미하는 https://google.com/과 같은 URL들은 마치 하나의 문자열 같아 보여도 사실은 여러 개의 구성 요소로 이루어져있다.

이때 출처는 ProtocolHost,port 번호까지 모두 합친 것을 의미한다. 서버의 위치를 찾아가기 위해 필요한 가장 기본적인 것들을 합쳐놓은 것이다. 출처 내의 포트 번호는 생략이 가능한데 이는 각 웹에서 사용하는 HTTP, HTTPS 프로토콜의 기본 포트 번호가 정해져있기 때문이다.

그러나 만약 https://google.com:443과 같이 출처에 포트 번호가 명시적으로 포함되어 있다면 이 포트 번호까지 모두 일치해야 같은 출처라고 인정된다.

SOP(Same-Origin Policy)

SOP는 “같은 출처에서만 리소스를 공유할 수 있다”라는 규칙을 가진 정책이다. 브라우저는 보안을 위해서 SOP를 만들었다. ex) XMLHttpRequest와 Fetch API

그러나 웹이라는 오픈스페이스 환경에서 다른 출처에 있는 리소스를 가져와서 사용하는 일은 굉장히 흔한 일이기 때문에 몇 가지 예외 조항을 두고 이 조항에 해당하는 리소스 요청은 출처가 다르더라도 허용하기로 했는데, 그 중 하나가 “CORS 정책을 지킨 리소스 요청”이다.

그래서 왜 이런 정책이 만들어진걸까?

브라우저의 개발자 도구를 열면 DOM이 어떻게 작성되어있는지, 어떤 서버와 통신하는지, 리소스의 출처는 어디인지와 같은 각종 정보들을 알 수 있다. 때문에 웹에서 돌아가는 클라이언트 어플리케이션은 사용자의 공격에 취약하다. 이런 상황 속에서 다른 출처의 어플리케이션이 서로 통신하는 것에 대해 아무런 제약도 존재하지 않는다면 악의를 가진 누군가가 사용자의 정보를 탈취하기가 쉬워지고 사용자가 악성 사이트로 접속할 수도 있다.

같은 출처의 구분

URL의 구성 요소 중 Scheme, Host, Port만 동일하면 된다.

CORS는 어떻게 동작하는가

어떤 방법을 통해 서로 다른 출처를 가진 리소스를 안전하게 사용할 수 있을까?

기본적으로 웹 클라이언트 어플리케이션이 다른 출처의 리소스를 요청할 때는 HTTP 프로토콜을 사용하여 요청을 보내게 되는데, 크로스 오리진 요청을 보낼 경우 브라우저는 항상 Origin(필드에 요청을 보내는 출처)을 헤더를 요청에 추가한다.

  1. https://google.com/어쩌구에서 https://anywhere.com/request에 요청을 보낸다고 가정해 보자. 헤더는 다음과 같은 형태가 된다.

GET /request
Host: anywhere.com
Origin: https://google.com/
...
  1. Origin 헤더엔 요청이 이뤄지는 페이지 경로(/어쩌구)가 아닌 오리진(도메인·프로토콜·포트) 정보가 담기게 된다.

Preflight

브라우저는 요청을 한번에 보내지 않고 예비 요청과 본 요청으로 나누어서 서버로 전송한다.

이때 브라우저가 본 요청을 보내기 전에 보내는 예비 요청을 Preflight(미리 전송)라고 부르는 것이며, OPTIONS 메서드를 통해 다른 도메인의 리소스로 HTTP 요청을 보내 실제 요청이 전송하기에 안전한지 확인한다.

이 과정에서 브라우저는 중재인의 역할을 한다

  1. 브라우저에게 리소스를 받아오라는 명령을 내린다
  2. 브라우저는 서버에게 예비 요청을 먼저 보낸다
  3. 서버는 예비 요청에 대한 응답으로 어떤 것들을 허용하고, 어떤 것들을 금지하고 있는지에 대한 정보를 응답 헤더에 담아서 브라우저에게 다시 보내준다
  4. 브라우저는 자신이 보낸 예비 요청과 서버가 응답에 담아준 허용 정책을 비교한 후, 이 요청을 보내는 것이 안전하다고 판단되면 본 요청을 보내게 된다
  5. 서버가 이 본 요청에 대한 응답을 하면 브라우저는 최종적으로 이 응답 데이터를 자바스크립트에게 넘겨준다

출처

profile
할 수 있다는 생각이 정말 나를 할 수 있게 만들어준다.

2개의 댓글

comment-user-thumbnail
2021년 7월 8일

선생님 저도 js, 리액트 해야하는데 포스트보니까 왤케 하기가싫ㅈㅕ... 딱봐도 넘나 어려워보이는것

1개의 답글