-
[web] 그놈의 CORS와 SOP 란Web 2022. 12. 17. 02:23
개요
최근 여러 프로젝트를 진행하다 CORS 오류를 자주 마주치게 되었다. 사실 CORS가 문제가 아니라 SOP이 문제라는 것도 레퍼런스들을 찾아보다 알게 되었다.
CORS는 Cross Origin Resource Sharing의 약자이다. Cross Origin 간의 Resource를 공유할 수 있도록 한다는 것인데 Cross Origin은 뭘까?
Cross Origin?
여기서 origin은 출처 즉, URL에서 protocol, hostname, port를 말한다.
그럼 Cross Origin은 protocol, hostname, port가 서로 다른 origin을 말한다.
근데 서로 다른 origin끼리 resource를 공유하는 것이 뭐 어쨋다는 말이지??
사실 문제는 SOP 때문이다.
SOP (Same Origin Policy)?
SOP은 동일 출처 정책이라고도 하며 같은 출처에서만 리소스를 공유할 수 있다는 규칙의 정책이다.
따라서 응답의 출처가 protocol, host, port 중 하나라도 다르면 SOP 오류가 뜨는 것이다.
In computing, the same-origin policy (SOP) is an important concept in the web application security model. Under the policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin. An origin is defined as a combination of URI scheme, host name, and port number. This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page through that page's Document Object Model.
출처: https://en.wikipedia.org/wiki/Same-origin_policySOP는 웹 애플리케이션 보안 모델에서 중요한 개념이다.
이 정책 하에 웹 브라우저는 어떤 한 웹 페이지에 포함된 스크립트가 다른 페이지에 있는 데이터를 접근하려할 때, 두 페이지의 출처(origin)이 같을 때만 접근을 허용한다.
따라서 이 정책은 어떤 한 웹 페이지에 있는 악성 스크립트가 다른 웹페이지에 있는 민감 정보를 DOM(Document Object Model)을 통해 접근하는 것을 막을 수 있다.
예시
SOP는 인증 정보 세션들이 다른 origin에서 사용되는 것을 막는다.
만약 SOP 가 없다면??
한 유저가 은행 업무 사이트에 로그인하고 로그아웃을 안했다고 해보자. 그리고 그 유저가 은행 사이트에 요청을 보내는 악성 스크립트가 있는 사이트를 방문했다고 하자. 유저가 아직 은행 사이트에 로그인 되어있기 때문에 악성 스크립트는 은행 사이트에서 인출, 예금 등 모든 작업을 할 수 있다.
은행 사이트 관리자는 일반적인 웹 브라우저가 악성 스크립트가 은행 관련 세션 쿠키나 플랫폼 수준의 권한에 접근하는 것을 원치 않을 것이다. 자바스크립트가 은행 관련 세션 쿠키에 직접적으로 접근 권한이 없다고 하지만, 은행 사이트에 은행 세션 쿠키를 가지고 요청을 보내거나 받을 수 있는 것은 사실이다.
따라서 SOP는 브라우저가 다른 출처에서 온 응답들이 읽기 권한을 얻는 것을 막는다.
CORS (Cross Origin Resource Sharing)
SOP을 완화(relaxing)시키는 방법 중 하나로,
CORS는 교차 출처 리소스 공유라고도 하며 SOP에 의한 접근 제한의 예외 조항으로, 사전 설정을 통해 리소스에 선택적으로 접근할 수 있도록 브라우저에 알려주는 정책이다. 즉, 브라우저는 SOP에 따라 기본적으로 다른 출처의 리소스 공유를 막지만, CORS를 통해 접근 권한을 얻을 수 있게 되는 것이다.
이는 Origin 요청 헤더와 Access-Control-Allow-Origin 응답 헤더를 통해 가능하다. 서버가 이 header를 사용해 데이터에 접근할 수 있는 Origin을 명시할 수 있도록 한다.
어떻게 CORS를 가능하게 할까?
여러 방법 중 하나로 서버에서 특정 도메인에 대해서만 접근을 허용하면 된다.
서버에서 Access-Control-Allow-Origin에 대한 정보를 헤더에 넣어 클라이언트에 넘겨주고 있다. 여기서는 *로 모든 도메인에 대한 접근을 허용하고 있다. 하지만 예를 들어 'jackcokebb.tistiory.com'으로 지정하면 'jackcokebb.tistiory.com'에서 온 요청만 서버가 받는다는 뜻이다.
사실 악의적으로 만든 서버에서 Access-Control-Allow-Origin: * 로 설정을 하면 클라이언트에서 보낸 쿠키와 세션 정보를 탈취하거나, 클라이언트에 해로운 데이터를 보내 해를 입힐 수 있지 않을까 싶긴하다. 추가적인 장치가 있을 것 같은데 찾아봐야겠다.
참고 및 출처:
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
https://en.wikipedia.org/wiki/Same-origin_policy
https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
https://www.geeksforgeeks.org/what-is-same-origin-policy-sop/