이 번역은 완료되지 않았습니다. 이 문서를 번역해 주세요.

동일 출처 정책은 문서나 스크립트가 다른 출처의 리소스와 통신하는 것을 제한하는 중요한 보안 방식입니다. 이것은 잠재적 악성 문서를 격리하여, 공격 경로를 줄이는데 도움이 됩니다.

출처의 정의

두 페이지의 프로토콜, 포트, 호스트가 동일하면 각 페이지의 출처도 동일합니다. "scheme/host/port 튜플"이나 그냥 "튜플"이라고 ("튜플"은 3개 이상의 요소가 전체를 구성하는 집합을 말합니다) 불리기도 합니다.

아래 테이블은 URL(http://store.company.com/dir/page.html)과 출처를 비교한 예시입니다.

URL 결과 이유
http://store.company.com/dir2/other.html 성공  
http://store.company.com/dir/inner/another.html 성공  
https://store.company.com/secure.html 실패 프로토콜 상이
http://store.company.com:81/dir/etc.html 실패 포트 상이
http://news.company.com/dir/other.html 실패 호스트 상이

file: URL을 위한 동일 출처 정책도 참고하세요.

출처 상속

about:blank나 javascript: URL이 있는 페이지에서 실행된 스크립트는 해당 URL로 열린 문서의 출처를 상속합니다. 왜냐하면 이러한 유형의 URL들은 명시적으로 서버의 출처가 포함되어 있지 않기 때문입니다. 예를 들어, about:blank는 부모 스크립트가 내용을 작성하는 빈 팝업 창에 자주 쓰입니다. 팝업 창에 코드가 포함되어 있으면, 해당 코드는 만들어진 스크립트와 동일한 출처를 상속합니다. data: URL들은 비어있는 새 보안 컨텍스트를 얻습니다.

IE 예외사항

인터넷 익스플로러(Internet Explorer)는 동일 출처 정책에 두가지 중요한 예외사항이 있다.

  • Trust Zones: 두 도메인이 highly trusted zone에 속하면(기업도메인 같은) 동일 출처 제약이 적용되지 않는다.
  • Port: IE는 포트는 비교하지 않는다. 따라서 http://company.com:81/index.htmlhttp://company.com/index.html은 동일출처로 여기며 제약이 적용되지 않는다.

위의 예외는 비표준이고 다른 브라우져에는 적용되지 않는다.

출처 변경

일부 제약이 있긴 하지만 페이지의 출처를 변경하는 것이 가능하다. 스크립트로 document.domain 의 값을 현재 도메인이나 현재 도메인의 상위 도메인으로 변경할 수 있다. 만약 도메인을 현재 도메인의 상위도메인으로 변경하면, 보다 짧은 도메인이 이후의 출처 확인에 사용된다. 예를 들어 http://store.company.com/dir/other.html 문서의 스크립트가 아래의 문장을 실행하면:

document.domain = "company.com";

문장이 실행된 이후에 페이지는 출처 체크에 http://company.com/dir/page.html 를 보낸다. 참고로, document.domain 의 값을 company.com 이 아닌 othercompany.com 으로 설정할 수는 없다. 왜냐하면 othercompany.com은 store.company.com의 상위 도메인이 아니기 때문이다.

포트 번호는 브라우저별로 유지된다. document.domain = document.domain 을 포함한 setter에 대한 모든 호출은 포트 번호를 null로 덮어쓸 것이다. 따라서 처음에 document.domain = "company.com" 만을 설정한다고 해서 company.com:8080 이 company.com 과 통신할 수는 없다. 양쪽 포트가 모두 null이 되도록 설정되어야 한다.

참고: 부모가 안전하게 접근하도록 하기 위해 document.domain을 사용한다면, 부모 도메인과 서브 도메인의 document.domain을 같은 값으로 설정해야 한다. 단순히 부모 도메인이 원래 값으로 설정되는 것이라고 해도 필수적이다. 이를 수행하는데 실패하면 권한 오류가 발생할 수도 있다.

Cross-origin 네트워크 접근

동일 출처 정책은 당신이 XMLHttpRequest 혹은<img> 요소를 사용할 때와 같은 두개의 다른 출처간의 상호작용을 조절한다. 이 상호작용들은 일반적으로 세개의 카테고리에 존재한다:

  • Cross-origin writes 는 일반적으로 허용된다. 링크, 리디렉션과 폼 sumissions가 그 예들이다. 아주 간혹 사용되는 특정 HTTP 요청에는 preflight가 필요하다.
  • Cross-origin embedding 은 일반적으로 허용된다. 아래에 예제들이 있다.
  • Cross-origin reads 는 일반적으로는 허용되지 않으나, 읽기 접근은 종종 임베딩에 의해 유출된다. 예를 들어 임베드된 이미지의 폭과 너비, 임베드된 스크립트의 액션, 임베드된 리소스의 가용성을 읽을 수 있다.

아래에는 임베드된 cross-origin 일지도 모르는 몇가지 리소스의 예제들이 있다:

  • <script src="..."></script>를 사용한 자바스크립트. 구문 오류에 의한 오류 메시지는 오직 같은 출처의 스크립트에서만 가능하다.
  • <link rel="stylesheet" href="...">을 사용한 CSS. CSS의 relaxed syntax rules 때문에, cross-origin CSS는 올바른 Content-Type 헤더가 필요하다. 제한은 브라우저에 따라 다르다: IE, Firefox, Chrome, Safari (CVE-2010-0051으로 스크롤 다운) 과 Opera.
  • <img> 을 사용한 이미지. 지원되는 이미지 포맷은 다음을 포함한다 : PNG, JPEG, GIF, BMP, SVG, ...
  • <video><audio> 를 사용한 미디어 파일.
  • <object>, <embed> 과 <applet>을 사용한 플러그인.
  • @font-face를 사용한 폰트. 몇몇 브라우저는 cross-origin 폰트를 허용하나, 그 외에는 동일 출처 폰트가 필요하다.
  • <frame> 과 <iframe>을 사용한 것. 사이트는 cross-origin 상호작용의 폼을 방지하기 위해 X-Frame-Options 헤더를 사용할 수도 있다.

Cross-origin 접근을 허용하는 방법

CORS 를 사용해 cross-origin 접근을 허용한다.

Cross-origin 접근을 방지하는 방법

  • cross-origin 쓰기를 막으려면, Cross-Site Request Forgery (CSRF) 토큰과 같이, 예측 불가능한 토큰을 요청에서 확인한다. 이 토큰을 알고있는 페이지에 대한 cross-origin 읽기는 무조건 막아야 한다.
  • cross-origin 리소스 읽기를 막으려면 그 리소스를 임베딩이 가능하지 않게 하면된다. 리소스가 임베딩되면 항상 그 정보가 새어나가는 것에 취약하기 때문에, 임베딩을 막는 것은 종종 필요하다.
  • cross-origin 임베딩을 막으려면, 리소스가 위의 임베딩 가능한 포맷 중의 하나로 해석될 수 없는지 확인한다. 대부분의 경우에 브라우저는 Content-Type을 지키지 않는다. 예를 들어 HTML 문서의 <script> 태그를 가리켰을 때, 브라우저는 HTML을 자바스크립트로 바꾸려고 할 것이다. 리소스가 사이트의 입구가 아닐 때에는 CSRF 토큰을 사용하여 임베딩을 방지할 수도 있다.

Cross-origin 스크립트 API 접근

JavaScript APIs such as iframe.contentWindow, window.parent, window.open and window.opener allow documents to directly reference each other. When the two documents do not have the same origin, these references provide limited access to the Window and Location objects. Some browsers allow access to more properties than the spec allows. You can use window.postMessage instead to communicate between documents.

Cross-origin 데이터 저장소 접근

Access to data stored in the browser such as localStorage and IndexedDB are separated by origin. Each origin gets its own separate storage, and JavaScript in one origin cannot read from or write to the storage belonging to another origin.

The window.name property can be used to temporarily store data, that can be accessed cross-origin.

Cookies use a separate definition of origins. A page can set a cookie for its own domain or any parent domain, as long as the parent domain is not a public suffix. Firefox and Chrome use the Public Suffix List to determine if a domain is a public suffix. Internet Explorer uses its own internal method to determine if a domain is a public suffix. The browser will make a cookie available to the given domain including any sub-domains, no matter which protocol (http/https) or port is used. When you set a cookie, you can limit its availability using the Domain, Path, Secure and Http-Only flags. When you read a cookie, you cannot see from where it was set. Even if you use only secure https connections, any cookie you see may have been set using an insecure connection.

함께 보기

원본 문서 정보

  • 저자: Jesse Ruderman

 

문서 태그 및 공헌자

이 페이지의 공헌자: TroyTae, midistour, seungha-kim, ryuan.choi, manascue, Vermond, behumble
최종 변경자: TroyTae,