브라우저 보안 정책에 SOP(same-origin-policy) 있다는 것을 알게 되었고, 어떤건지 궁금해서 찾아보았다. 마침 MDN 문서에 잘 나와있어서 이를 참조할 수 있었다.

Same-Origin-Policy(동일 출처 정책)


sop

  • SOP는 한 Origin에서 로드된 문서 또는 스크립트가 다른 Origin의 리소스와 상호 작용할 수 있는 방법을 제한하는 중요한 보안 메커니즘이다.

  • 보안을 위협하는 문서를 격리하여, 보안 위협으로부터 보호할 수 있다.

  • 한마디로 말해서 웹 브라우저에서 동작하는 프로그램은 로딩된 위치에 있는 리소스만 접근 할 수 있다는 정책이다.

출처(Origin)의 정의


origin

  • 두개의 URL이 존재할 때 프로토콜, 포트(지정된 경우), 호스트가 동일한 경우 두 URL의 Origin이 같다.

  • 위의 표를 보면 http://store.company.com/dir/page.html 과 비교하여, 같은 Origin인지 아닌지를 나타내고 있다.

상속된 출처(Origin)


inherited origins

  • about:blank, javascript:URL과 같은 URL이 포함된 페이지에서 실행되는 스크립트는 해당 URL에 포함된 문서의 원본을 상속합니다.

  • 이러한 유형의 URL에는 원본 서버에 대한 정보가 포함되어 있지 않기 때문입니다.

Internet Explorer의 예외

항상 인터넷 익스플로러는 표준을 지키지 않아서 문제가 생기는 것 같다.

Trust Zones

만약 두 도메인이 모두 신뢰도가 높은 영역 (예: 회사 인트라넷 도메인)에 있는 경우 동일한 오리진 제한이 적용되지 않는다.

Port

IE는 동일 출처 검사에 포트를 포함하지 않는다. 따라서 https://company.com:81/index.htmlhttps://company.com/index.html은 같은 오리진으로 간주되며 제한은 적용되지 않는다.

출처(Origin)를 변경하기


  • 일부 제한 사항이 있는 페이지는 자체 출처를 변경할 수 있다.
  • 스크립트는 document.domain의 값을 현재 도메인 또는 현재 도메인의 슈퍼 도메인으로 설정할 수 있다.
  • 하지만 이 기능은 동일한 출처 정책에서 제공하는 보안 보호 기능을 약화시키고 브라우저의 출처 모델을 복잡하게 하여, 상호 운용성 문제와 보안 버그를 유발하기 때문에 더 이상 사용되지 않는다.

Document.domain

  • API 문서를 보더라도, 몇몇의 브라우저가 지원을 하더라도, 지금은 표준에서 제외되었고 사용하지 않는게 좋다고 나와있다.

  • 현재 디프리케이트 상태이다.

서로 다른 출처 접근(Cross-origin network access)


another origin

동일 출처 정책은 XMLHttpRequest 또는 img 요소를 사용하는 경우와 같이 서로 다른 두 출처 간의 상호 작용을 제어한다. 이러한 상호작용은 다음과 같은 세 가지의 범주로 나누어진다.

동일 출처 정책에 대한 처리


download

  • 만약 웹 사이트 http://sitea.com에서 자바스크립트를 로딩 한 다음에 이 스크립트에서, http://api.my.com을 호출한다면 동일 출처 정책에 의해서 호출한다면 호출 에러가 발생한다.

  • 이를 해결하는 방법으로는 인프라 측면에서 프록시를 사용하는 방법이나 JSONPCORS(Cross Origin Resource Sharing)이라는 방법이 있다.

프록시를 이용하는 방법

  • 프록시를 이용하는 경우에는 간단하게 해결된다. 동일 출처 정책의 문제는 API 서버와 자바 스크립트가 호스팅 되는 서버의 URL이 달라서 문제가 발생하게 된다. 이를 앞단에 Reverse Proxy를 넣어서 전체 URL이 같게 만들어주면 된다.

  • 이러한 구조가 되면, 자바 스크립트가 로딩된 사이트도 mysite.com이 되고 자바스크립트에서 호출하고자 하는 API URL도 mysite.com이 되기 때문에 동일 출처 정책에 위배되지 않는다.

  • 이 방식은 간단하지만, 자사의 웹 사이트를 서비스하느 경우에만 가능하다. 그래서 자사의 서비스용 API를 만드는 경우에는 괜찮지만, 파트나사나 일반 개발자에게 자바스크립트용 REST API를 공개하는 경우에는 적절하지 않다.

특정 사이트에 대한 접근 허용 방식

  • CROS 방식 중 이 방식은 가장 간단한 방식으로, API 서버의 설정에서 모든 소스에서 들어오는 API 호출을 허용하는 것이다.

  • 이는 HTTPAPI를 호출하였을 때 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 URLHTTP 메서드를 반환해준다. 이를 Pre-flight 호출이라고 하는데, 이 정보를 바탕으로 해당 URLXMLHttpRequest를 보낼 수 있다.

  • 일반적으로는 교차 오리진 쓰기가 허용된다, 예를 들어 링크, 리디렉션 및 form 제출이 있다. 일부 HTTP 요청에서는 preflight 가 필요하다.

preflight_correct

  • preflight 요청이란 일반적인 요청과 다르게, 먼저 OPTIONS 메서드를 사용하여 HTTP 요청을 다른 출처(Origin) 리소스로 전송하여 실제 요청이 안전한지 확인하는 것이다.

  • 교차 사이트 요청은 사용자 데이터에 영향을 미칠 수 있으므로 preflight을 사용한다.

  • 서버는 이 URL에 대한 접근 권한을 반환한다, CORS 접근이 가능한 Origin 사이트를 반환하고 사용할 수 있는 메서드를 반환한다. 그리고 Pre-flight 호출은, Access-Control-Max-Age에 정의된 86400 초 동안 유효하다. (한번 Pre-flight 호출을 하고 나면, 이 시간 동안은 다시 Pre-flight 호출을 할 필요가 없다)

  • 이러한 CORS 설정은 API 호출 코드에서 직접 구현할 수 도 있고 로드 밸런서 역할을 하는 HAProxyNginx 같은 리버스 프록시 설정을 통해서 간단하게 처리할 수도 있다.

  • 만약 API 단에서 구현이 필요하더라도, HTTP 헤더를 직접 건드리지 않아도 스프링 등의 프레임워크에서 이미 CORS 구현을 지원하고 있으므로 프레임워크를 통해서 간단하게 구현하는 것을 추천한다.

참고 문헌


>> Home