브라우저 보안 정책에 SOP(same-origin-policy)
있다는 것을 알게 되었고, 어떤건지 궁금해서 찾아보았다. 마침 MDN 문서에 잘 나와있어서 이를 참조할 수 있었다.
Same-Origin-Policy(동일 출처 정책)
-
SOP
는 한Origin
에서 로드된 문서 또는 스크립트가 다른Origin
의 리소스와 상호 작용할 수 있는 방법을 제한하는 중요한 보안 메커니즘이다. -
보안을 위협하는 문서를 격리하여, 보안 위협으로부터 보호할 수 있다.
-
한마디로 말해서 웹 브라우저에서 동작하는 프로그램은 로딩된 위치에 있는 리소스만 접근 할 수 있다는 정책이다.
출처(Origin)의 정의
-
두개의 URL이 존재할 때 프로토콜, 포트(지정된 경우), 호스트가 동일한 경우 두 URL의
Origin
이 같다. -
위의 표를 보면 http://store.company.com/dir/page.html 과 비교하여, 같은
Origin
인지 아닌지를 나타내고 있다.
상속된 출처(Origin)
-
about:blank
,javascript:URL
과 같은 URL이 포함된 페이지에서 실행되는 스크립트는 해당 URL에 포함된 문서의 원본을 상속합니다. -
이러한 유형의 URL에는 원본 서버에 대한 정보가 포함되어 있지 않기 때문입니다.
Internet Explorer의 예외
항상 인터넷 익스플로러는 표준을 지키지 않아서 문제가 생기는 것 같다.
Trust Zones
만약 두 도메인이 모두 신뢰도가 높은 영역 (예: 회사 인트라넷 도메인)에 있는 경우 동일한 오리진 제한이 적용되지 않는다.
Port
IE는 동일 출처 검사에 포트를 포함하지 않는다. 따라서 https://company.com:81/index.html
과 https://company.com/index.html
은 같은 오리진으로 간주되며 제한은 적용되지 않는다.
출처(Origin)를 변경하기
- 일부 제한 사항이 있는 페이지는 자체 출처를 변경할 수 있다.
- 스크립트는
document.domain
의 값을 현재 도메인 또는 현재 도메인의 슈퍼 도메인으로 설정할 수 있다. - 하지만 이 기능은 동일한 출처 정책에서 제공하는 보안 보호 기능을 약화시키고 브라우저의 출처 모델을 복잡하게 하여, 상호 운용성 문제와 보안 버그를 유발하기 때문에 더 이상 사용되지 않는다.
-
API 문서를 보더라도, 몇몇의 브라우저가 지원을 하더라도, 지금은 표준에서 제외되었고 사용하지 않는게 좋다고 나와있다.
-
현재 디프리케이트 상태이다.
서로 다른 출처 접근(Cross-origin network access)
동일 출처 정책은 XMLHttpRequest
또는 img
요소를 사용하는 경우와 같이 서로 다른 두 출처 간의 상호 작용을 제어한다. 이러한 상호작용은 다음과 같은 세 가지의 범주로 나누어진다.
동일 출처 정책에 대한 처리
-
만약 웹 사이트
http://sitea.com
에서 자바스크립트를 로딩 한 다음에 이 스크립트에서,http://api.my.com
을 호출한다면 동일 출처 정책에 의해서 호출한다면 호출 에러가 발생한다. -
이를 해결하는 방법으로는 인프라 측면에서 프록시를 사용하는 방법이나
JSONP
와CORS(Cross Origin Resource Sharing)
이라는 방법이 있다.
프록시를 이용하는 방법
-
프록시를 이용하는 경우에는 간단하게 해결된다. 동일 출처 정책의 문제는
API
서버와 자바 스크립트가 호스팅 되는 서버의 URL이 달라서 문제가 발생하게 된다. 이를 앞단에Reverse Proxy
를 넣어서 전체 URL이 같게 만들어주면 된다. -
이러한 구조가 되면, 자바 스크립트가 로딩된 사이트도
mysite.com
이 되고 자바스크립트에서 호출하고자 하는API
URL도mysite.com
이 되기 때문에 동일 출처 정책에 위배되지 않는다. -
이 방식은 간단하지만, 자사의 웹 사이트를 서비스하느 경우에만 가능하다. 그래서 자사의 서비스용
API
를 만드는 경우에는 괜찮지만, 파트나사나 일반 개발자에게 자바스크립트용REST API
를 공개하는 경우에는 적절하지 않다.
특정 사이트에 대한 접근 허용 방식
-
CROS 방식 중 이 방식은 가장 간단한 방식으로,
API
서버의 설정에서 모든 소스에서 들어오는API
호출을 허용하는 것이다. -
이는
HTTP
로API
를 호출하였을 때 HTTP에 요청에 응답을 주면서 HTTP 헤더에Request Origin
(요청을 처리해 줄 수 있는 출처)를 명시하는 방식이다. -
api.my.com
에서 응답 헤더에 다음과 같이 명시해주면sitea.com
에 의해서 로딩된 자바스크립트 클라이언트 요청에 대해서만api.my.com
이 요청해준다.
Access-Controll-Allow-Origin: sitea.com
- 만약에 다음과 같이
*
로 해주면Request Origin
에 관계없이 사이트에서 로딩된 자바스크립트 요청에 대해서 처리해준다.
Access-Control-Allow-Origin: *
Pre-flight를 이용한 세세한 CORS 통제
-
REST
리소스(URL)당 섬세한CORS
통제가 필요한 경우에는Pre-Flight
호출이라는 것을 이용할 수 있다. -
이 방식은
REST
리소스를 호출하기 전에, 웹 브라우저가HTTP OPTIONS
요청을 보내면 해당REST
리소스에 대해서 가능한CORS
정보를 보내준다. (접근이 허용된 사이트, 접근이 허용된 메서드 등) -
웹 브라우저에서는
XMLHttpRequest
를 특정URL
로 요청하기 전에,HTTP OPTIONS
를 호출한다. 그러면 서버는 해당URL
에 접근할 수 있는Origin URL
과HTTP
메서드를 반환해준다. 이를Pre-flight
호출이라고 하는데, 이 정보를 바탕으로 해당URL
에XMLHttpRequest
를 보낼 수 있다. -
일반적으로는 교차 오리진 쓰기가 허용된다, 예를 들어 링크, 리디렉션 및
form
제출이 있다. 일부 HTTP 요청에서는 preflight 가 필요하다.
-
preflight
요청이란 일반적인 요청과 다르게, 먼저OPTIONS
메서드를 사용하여 HTTP 요청을 다른 출처(Origin
) 리소스로 전송하여 실제 요청이 안전한지 확인하는 것이다. -
교차 사이트 요청은 사용자 데이터에 영향을 미칠 수 있으므로
preflight
을 사용한다. -
서버는 이
URL
에 대한 접근 권한을 반환한다,CORS
접근이 가능한Origin
사이트를 반환하고 사용할 수 있는 메서드를 반환한다. 그리고Pre-flight
호출은,Access-Control-Max-Age
에 정의된86400
초 동안 유효하다. (한번Pre-flight
호출을 하고 나면, 이 시간 동안은 다시Pre-flight 호출을 할 필요가 없다
) -
이러한
CORS
설정은API
호출 코드에서 직접 구현할 수 도 있고 로드 밸런서 역할을 하는HAProxy
나Nginx
같은 리버스 프록시 설정을 통해서 간단하게 처리할 수도 있다. -
만약
API
단에서 구현이 필요하더라도,HTTP
헤더를 직접 건드리지 않아도 스프링 등의 프레임워크에서 이미CORS
구현을 지원하고 있으므로 프레임워크를 통해서 간단하게 구현하는 것을 추천한다.
참고 문헌
>> Home