CORS란 무엇인가?

정관우·2021년 7월 23일
0
post-thumbnail

CORS란?

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 브라우저가 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제 - MDN

좀 더 쉽게 말하자면, 사용자가 지금 접속한 사이트와 다른 출처의 리소스를 사용하려 할 때 브라우저가 참고하는 화이트 리스트라고 할 수 있다. 만약, 이 리스트에 없다면 콘솔 창에 빨간 색 CORS 에러를 맞닥뜨리게 될 것이다.

Why CORS?

그렇다면 왜 브라우저는 나를 막는 것일까? 나를 못 믿는 것인가? 아니다.

브라우저는 내가 방문한 사이트를 믿지 못하는 것이다. 브라우저는 우리가 웹 사이트를 이용할 때 굉장히 민감한 정보들을 저장하고 있다. 로그인 상태를 유지하기 위해 브라우저는 토큰 등의 정보를 쿠키로 저장하여 요청을 보낼 것이다.

이러한 인증 정보는 해커들의 타겟이 될 수 있다. 해커들은 정보를 빼내기 위해 사용자를 자신이 만든 사이트에 들어오게끔 유도한다. 만약, 사용자가 사이트에 접속한다면 브라우저에서 해커의 악성 코드가 실행되어 인증 정보를 탈취할 수도 있다. 즉, 내 의지와 상관없이 브라우저에 저장된 정보로 악의적인 행동을 취할 수 있다.

이러한 일들을 방지하기 위해서, 브라우저는 허용된 사이트 (CORS) 이외에 다른 사이트로의 요청이 갈 수 없게끔 사용자를 보호하고 있는 것이다. 엄밀히 말하자면, 요청을 막는 것은 동일 출처 정책 (Same-Origin Policy, SOP) 이 하고 있는 것이다.

등장 배경

원래 보안을 위해 다른 출처의 리소스를 접근하는 것이 불가능했지만, 웹 생태계가 다양해지면서 여러 서비스들끼리 자유롭게 데이터가 주고 받아질 필요가 생겼다. 그런데, 다른 사이트 간의 요청들을 브라우저가 막고 있기 때문에 이를 허용해주기 위해 어떠한 기준을 충족시키면 리소스를 공유할 수 있도록 만들어진 체제가 바로 CORS다.

CORS의 동작원리

CORS 동작의 시나리오는 다음 2가지로 나뉜다.

1. Simple Request

: 예비 요청을 보내지 않고, 서버에게 바로 본 요청을 전송한다. 이 후 서버가 응답 헤더에

Access-Control-Allow-Origin과 같은 값을 보내주면 그때 브라우저가 CORS 정책 위반 여부를 검사하는 방식이다. GET이나 POST 등 일정 조건에 요청들에 대해 사용된다.

  1. 기본적으로 웹은 다른 출처의 리소스를 요청할 때는 HTTP 프로토콜을 사용하여 요청을 하는데, 이때 브라우저는 요청 헤더에 Origin 필드에 요청을 보내는 출처를 담아 전송한다.
  2. 서버는 요청에 대한 응답을 하는데, 응답 헤더에 Access-Control-Allow-Origin이라는 항목에 이 리소스를 접근하는 것이 허용된 출처를 명시해준다. 이후, 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 Access-Control-Allow-Origin을 비교한 후 이 응답 가능 여부를 결정한다.

2. Prefilght Request

: 요청을 한번에 보내는 것이 아닌 예비 요청과 본 요청으로 나누어서 서버로 전송한다. 본 요청을 보내기 전 미리 예비로 보내는 요청을 Preflight라고 하며, HTTP 메서드 중 OPTIONS 메서드를 사용한다. 서버는 예비 요청에 대한 응답으로, 어떤 요청을 허용하고 또 금지하는지에 대한 정보를 응답 헤더에 담아 보낸다. 예비 요청으로 본 요청이 안전한지 확인한 다음에야 본격적으로 요청을 보낼 수 있다. PUT이나 DELETE 등 서버 데이터에 영향을 줄 수 있는 요청들이기 때문에 먼저 요청의 허용 여부를 검증하는 것이다.

만약, 토큰 등 사용자 식별 정보가 담긴 요청에 대해서는 보다 엄격하다. 요청 옵션에 crendentials 항목을 true로 세팅해야 하고, 서버에서도 모든 출처를 허용하는 와일드카드 (*)가 아닌 요청 웹페이지의 주소를 정확히 명시한 다음 Access-Control-Allow-Credentials 항목을 true로 설정해주어야 한다.

참고 자료
교차 출처 리소스 공유 (CORS) - MDN
[Browser] CORS란? - Beomy
CORS란 무엇인가? - pilyeooong

profile
작지만 꾸준하게 성장하는 개발자🌳

0개의 댓글