본문 바로가기
보안/네트워크 보안

SOP

by oncerun 2021. 5. 22.
반응형

동일 출처 정책(same-origin policy)은 어떤 출처에서 불러온 문서나 스크립트가 다른 출처에서 가져온 리소스와 상호작용하는 것을 제한하는 중요한 보안 방식입니다. 동일 출처 정책은 잠재적으로 해로울 수 있는 문서를 분리함으로써 공격받을 수 있는 경로를 줄여줍니다. - mozilla-

 

 

다음은 모질라에서 sop에 대한 정의입니다. 한 origin으로부터 로드된 document 또는 script가 다른 origin의 리소스와 상호 작용을 제한하는 중요한 보안 방식입니다. 여기서 주목해야 할 것은 문서와 스크립트입니다.

 

우선 개발자 도구를 켜서 현재 origin이 어떻게 구성되어 있는지 확인해 보겠습니다.

현재 페이지의 오리진입니다. 오리진은 3가지로 구성되어 있습니다.

 

1. SCHEME : https://를 의미합니다.

 

2. HOST : chinggin.tistory.com 를 의미합니다. 

 

3. PORT : https는 기본적으로 443 포트를 이용하며 현재는 생략되어 있는 것을 알 수 있습니다.

 

따라서 웹브라우저가 SOP정책을 실행하는 기준은 위의 Scheme, host, port번호가 다르고 response header에  Access-Control-Allow-Origin 값에 현재 origin의 값이 없을 때 요청 데이터를 읽는 행위를 막습니다.

 

그리고 유명한 다음과 같은 error를 보게되는 것입니다.

 

document에서 어떠한 상황에서 SOP정책이 적용될까요?

 

1. 다른 호스트 리소스에 AJAX요청을 보내고 응답 데이터를 읽을 경우

 

 - 사실 Prefight요청을 제외하고 외부 호스트에 요청을 보낼 수는 있습니다. 하지만 해당 데이터를 읽을 때 같은 origin이 아니면 null값을 리턴해주어서 오류가 발생하는 것이죠.

 

2. window.open()을 통해 새로운 document를 로딩한 경우 기존 origin과 다른 경우에 서로 간의 document에 접근할 수 없고 극히 제한적인 객체에만 접근이 가능합니다.

 

3.iframe을 사용한 경우에도 2번과 동일합니다.

 

또한 웹 브라우저에는 local환경에 저장하는 localStorage와 sessionStorage가 있는데 이 로컬 저장소에는 origin마다 하나씩 생성되고 접근 또한 same-origin이 같은 document나 script만 접근이 가능합니다.

 

즉 iframe.content , window.parent , window.open, window.opener 할 때 same-origin이 아니고 cross-origin인 경우에는 많은 제약을 두겠다는 정책입니다.

 

만약 Cross-Origin간의 데이터 전송이 필요한 경우에는 document상에서는 어떻게 해야 할까요? 

이 경우에는 window.postMessage()를 이용하여 백엔드와 프런트엔드 구성을 통하여 할 수 있습니다.

하지만 다른 방법도 있습니다.

 

 

 

왜 SOP가 중요하고 정의에서 보안 메커니즘이라고 하는 걸까요?

 

만약 SOP가 없는 상황에 다음과 같은 상황이 발생 할 수 있습니다.

 

 

여기서 SOP라고 모든걸 막지는 않습니다. Cross-Origin에 요청을 보내는 것은 가능합니다. 다만 preflight는 제외합니다.

그리고 우리가 외부 CDN에서 스크립트를 다운로드하는 것처럼 script, iframe, css, img, video, audio 등 document에 포함되어 로딩하는 것은 가능합니다. 그렇기에 의도치 않게 정보의 노출이 가능합니다. 로그인의 여부나, 콘텐츠 등이 노출될 수 있습니다만 조작이 불가능한 것이죠.

 

 

그럼 Cross-Origin간의 데이터 통신이 필요한 경우에는 어떻게 해야 할까요? 공공 API를 이용해야 하는데 어떻게 해야 할까요?

 

우선 공공 API를 이용할 경우를 생각해 봅니다. 공공 API는 요청을 보내기 위한 개발 명세서가 작성되어 있습니다. 

해당 데이터를 요청할 때 어떻게, 어떠한 방식으로 보내야 한다라는 정책이 정해저 있고, 서버 측에서 해당 정책을 구현해 놓았기 때문에 설명이 불친절할 경우는 답이 없습니다. 

 

다음은 공공데이터 포탈의 코로나에 대한 공공 API 사용법을 제공합니다.

https://www.data.go.kr/data/15043078/openapi.do

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

 

 

get방식으로 인증키와 요청 파라미터를 보내면 응답이 내려온다고 했으니, 해당 인증키가 존재하면 요청되어서 온 origin에게 데이터를 읽는 걸 허용하는 것 같습니다.

 

 

공공 API를 이용할 때 CORS가 발생한다면 개발 명세서를 잘 읽어보아야 합니다. 제공되는 예시와 설명에 따라 공공 API 서버의 사양이 구현되어 있기 때문에 다른 방법은 막아 놨을 가능성이 큽니다.

 

혹은 SOP는 브라우저에서 적용하는 보안정책이기 때문에 서버와 서버 간의 통신을 통하여 데이터를 받고 해당 document에 전달하는 것은 상관이 없기 때문에 서버끼리 통신을 하는 것도 하나의 방법일 수 있습니다.

 

 

만약 벡엔드와 프런트엔드가 개별 서버를 가지고 프로젝트를 한다고 했을 경우, 백엔드 측에서 요청에 대한 응답 헤더에 해당 오리진을 추가해 준다면 브라우저가 헤더 값을 읽어서 일치한다면 데이터를 프런트에서 읽을 수 있을 것입니다.

 

또 다른 방법으로는 JSONP방식이 존재합니다.

 

스크립트가 임베디드 되어 실행된다는 것을 통해 SOP를 우회하는 방법으로 모든 Origin을 대상으로 SOP를 무력화시키는 방식입니다.  콜백 함수를 지정해 놓고 서버에  해당 스크립트를 실행하는 코드를  반환하며 해당 콜백 함수의 인자에 요청한 데이터를 넣어서 올 수 있습니다.  스크립트를 임베딩 시킬 수 있는 방법으로 우회한 것입니다. 따라서 JSONP방식은 추천하지 않으며, 레거시에 구현되어 있는 경우에 CORS로 마이그레이션을 하는 것이 좋습니다.

 

 

정리하자면 공공 API는 개발 명세서를 잘 읽어야 하며, CORS정책을 이용하여 다른 Origin 간의 상호작용을 허용하며 이 경우 *을 사용해 모든 도메인에 열여 놓는 것도 보안상 위험하며, trick인 JSONP는 사용하지 말자!

 

반응형

'보안 > 네트워크 보안' 카테고리의 다른 글

TLS/SSL 아키텍처  (0) 2022.01.27
웹 보안 프로토콜  (0) 2021.02.28
암호 기법  (0) 2021.02.28
네트워크 보안 위협 유형  (0) 2021.02.28
네트워크 보안 개요  (0) 2021.02.28

댓글