CORS

SeokHwan An·2022년 10월 20일
0


CORS문제를 처음 직면한 때는 프론트와 백엔드를 나누어서 개발할 때 였습니다. 백엔드 개발을 어느정도 완성되고 프론트 팀원들과 연동해서 화면에 자원들이 잘 나타나는지 확인을 할 때 위와 같은 오류가 발생하며 저를 당황하게 했습니다..

CORS가 뭐지..?

CORS

CORSCross-Origin Resource Sharing의 약자로 출처가 다른 자원들을 공유한다는 의미입니다. 즉, 자기 영역(같은 출처)에 있는 리소스를 요청하는 것이 아닌 다른 영역(다른 출처)에 리소스를 요청할 때 발생하는 교차 요청이라고 할 수 있습니다.

더 쉽게 생각하면 우리가 다른 사람들의 물건을 사용해야 하는 상황이 올 때 우리는 당연히 그 당사자에게 허락을 구하고 물건을 사용하는 상황하고 비슷하다고 보면 될 것 같습니다.

여기서 말하는 같은 출처다른 출처는 어떻게 구분하는 것일까요?
먼저 URL을 보면서 간다하게 설명하겠습니다.

위의 사진은 port 번호가 생략되어 있지만 같은 출처라고 하면 Protocol + Host + Port가 같은 것을 의미합니다.

다시 우리가 직면한 문제 상황을 보면 스프링은 8080포트를 사용하고 리엑트는 3000포트를 사용하기에 다른 출처에 해당되어 CORS문제가 발생하게 되었습니다.

왜 사용하는가?

먼저 사용하는 이유는 보안상의 이유로 사용하게 된 것입니다. 이 이야기는 밑에 다시 설명하겠습니다.

사실 나는 이 개념이 왜 사용되는지 프로젝트를 하는 중에는 이해가 잘 되지 않았습니다. 기간도 많이 남지 않은 상황이었기에 당시에는 해결하는데 급급했기 때문입니다. 프로젝트가 끝나고 다시 곰곰히 찾아보았습니다.

사실 CORS외에도 다른 출처의 리소스를 사용하는 것을 제한하는 정책이 하나 더 있었는데 이는 SOP(Same-Origin Policy)였습니다. 이름 그대로 같은 출처에서만 리소스를 공유할 수 있다라는 규칙을 가지고 있었습니다. 하지만 대부분의 웹 서비스가 프론트와 백엔드가 각각의 환경에서 개발이 되는데 그러면 SOP를 무시하는 것이 아닌가? 맞다면 맞는 말이고 아니면 아니다고 할 수 있는데 이는 SOP에서도 예외상황을 두고 있기 때문입니다.

SOP에 대한 설명을 보면 그 이유를 알 수 있습니다.

Access to network resources varies depending on whether the resources are in the same origin as the content attempting to access them.

Generally, reading information from another origin is forbidden. However, an origin is permitted to use some kinds of resources retrieved from other origins. For example, an origin is permitted to execute script, render images, and apply style sheets from any origin. Likewise, an origin can display content from another origin, such as an HTML document in an HTML frame. Network resources can also opt into letting other origins read their information, for example, using Cross-Origin Resource Sharing.

RFC 6454 - 3.4.2 Network Access

이렇듯 SOP에서도 예외상항을 두되 CORS를 만족하는 상황에 대해서만 다른 출처에 리소스를 사용할 수 있게 해두었습니다.

다시 돌아와서 이렇게까지 보안상의 정책을 만들면서까지 다른 출처에 접근하는 것을 막는 이유는 웹 자체가 보안상의 문제가 많다는 것입니다. 그 예로 개발자 도구를 이용해서 개발된 정보(어떤 서버와 통신하는지, DOM이 어떻게 작성되었는지 등등)들을 파악할 수 있습니다.

이러한 상황 속에서 다른 출처에서 리소스를 접근할 때 한 없이 허용을 해준다면 CSRF나 XXS를 활용해 개인정보가 담긴 리소스를 쉽게 탈취할 수 있을 것입니다. 그렇기에 이와 같은 정책들을 제시하면서까지 보안을 높이는 것이라고 할 수 있습니다.

어떤 원리로 작동하는가

이제 CORS가 어떤 방식으로 허용된 다른 출처 리소스를 가져오는 방식에 대해 알아보겠습니다.

클라이언트와 서버가 통신하는데는 http message를 통해 통신이 이루어지는데 header를 보면 Origin이라는 필드가 있습니다. 클라이언트는 요청을 보낼 때 자신의 출처를 제공합니다. 이에 서버는 요청에 따른 응답을 보낼 때 헤더 필드인 Access-Control-Allow-Origin이라는 값에 "허용된 출처"를 보내게 되고, 이 두 필드의 값을 비교하여 유요한 값인지 아닌지 파악하는 것입니다.

여기서 의문점이 생길 수 있는데 이와 같은 필드에 출처를 주고 받는다고 한들 프론트나 백앤드에서 두 필드를 비교하는 로직을 구현해본 사람은 없었을 것입니다. 이는 브라우저 내에 비교하는 기능 탑재되어 있어 개발자들은 고려할 필요가 없습니다. 밑의 그림을 보면 쉽게 이해할 수 있습니다.

결국 서버는 다른 출처에 요청이 들어와서 리소스를 제공을 하기에 log기록이 남게 되는데 백엔드 개발자들은 오류가 발생했을 시 잘 구분해서 읽을 수 있어야 합니다.

정리

이 포스트를 작성하면서 CORS가 무엇인지 왜 사용하는지에 대해서 알 수 있었습니다. 이를 해결하는 방안도 있을 텐데 이는 다음 포스트에서 자세하게 정리하도록 하겠습니다.

https://evan-moon.github.io/2020/05/21/about-cors/
https://beomy.github.io/tech/browser/cors/

0개의 댓글