{{위키데이터 속성 추적}}
{{HTTP}}
'''동일-출처 정책'''({{llang|en|same-origin policy}}, '''SOP''')는 [[웹 애플리케이션]]의 중요한 [[보안 모델]]이다.

정책에 따라 웹 브라우저는 첫 번째 웹 페이지에 포함된 스크립트가 두 번째 웹 페이지의 데이터에 액세스하는 것을 허용하지만 두 웹 페이지의 출처가 동일한 경우에만 허용된다. 출처는 URI 체계, 호스트 이름 및 포트 번호의 조합으로 정의된다. 이 정책은 한 페이지의 악성 스크립트가 해당 페이지(DOM)를 통해 다른 웹 페이지의 민감한 데이터에 액세스하는 것을 방지한다.

이 메커니즘은 서버가 HTTP 쿠키 정보를 기반으로 중요한 정보를 공개하거나 상태 변경 작업을 수행하기 때문에 인증된 사용자 세션을 유지하기 위해 HTTPScookies에 광범위하게 의존하는 최신 웹 애플리케이션에 특히 중요하다. 데이터 기밀성 또는 무결성의 손실을 방지하려면 클라이언트 측에서 관련되지 않은 사이트에서 제공하는 콘텐츠를 엄격하게 분리해야 한다.

동일-출처 정책은 주로 스크립트로부터의 데이터 접근에 적용된다. 즉, 일치하는 HTML 태그를 경유하는 이미지, CSS, 스크립트 등 출처를 경유하여 리소스를 임베드하는 것은 제한되지 않는다.<ref>{{웹 인용|url=https://www.w3.org/2001/tag/2011/02/security-web.html|title=Security on the Web|last=Kemp|first=John|date=2011-02-04|quote=The same-origin policy states that a document from one unique origin may only load resources from the origin from which the document was loaded. In particular this applies to XMLHttpRequest calls made from within a document. Images, CSS and dynamically-loaded scripts are not subject to same-origin policy.|access-date=2018-07-24}}</ref> (글꼴은 잘 알려진 예외임<ref>{{웹 인용|url=https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face|title=@font-face|website=MDN Web Docs|language=en-US|access-date=2018-07-24|quote=Web fonts are subject to the same domain restriction (font files must be on the same domain as the page using them), unless HTTP access controls are used to relax this restriction.}}</ref>) 공격은 동일한 출처 정책이 HTML 태그에 적용되지 않는다는 사실을 이용한다.

== 역사 ==
동일 출처 정책의 개념은 넷스케이프 2.0에 자바스크립트가 도입된 직후인 1995년 넷스케이프 내비게이터 2.02에 의해 도입되었다. 자바스크립트는 웹 페이지에서 스크립팅을 가능하게 하며 특히 DOM([[문서 객체 모델]])에 대한 프로그래밍 방식의 액세스를 가능하게 한다.

이 정책은 원래 DOM에 대한 액세스를 보호하기 위해 설계되었지만 이후 전역 자바스크립트 개체의 민감한 부분을 보호하도록 확장되었다.

==구현==
모든 최신 브라우저는 중요한 보안 초석인 동일 출처 정책을 어떤 형태로든 구현한다. 정책은 정확한 사양과 일치할 필요는 없지만 [[마이크로소프트 실버라이트]], [[어도비 플래시]] 또는 [[어도비 애크러뱃]]과 같은 다른 웹 기술이나 [[XMLHttpRequest]]와 같은 직접적인 DOM 조작 이외의 메커니즘에 대해 대략 호환되는 보안 경계를 정의하기 위해 확장되는 경우가 많다.

== 출처 결정 규칙 ==
URI의 "출처"를 계산하는 데 사용되는 알고리즘은 RFC 6454, 섹션 4에 지정되어 있다. 절대 URI의 경우 출처는 삼중 {scheme, 호스트, 포트}이다. URI가 계층적 요소를 명명 권한으로 사용하지 않거나(RFC 3986, 섹션 3.2 참조) URI가 절대 URI가 아닌 경우 전역적으로 고유한 식별자가 사용된다. 두 리소스는 모든 값이 정확히 동일한 경우에만 동일한 출처로 간주된다.

설명을 위해 다음 표에서는 URL <nowiki>"http://www.example.com/dir/page.html"</nowiki>에 대한 검사의 일반적인 결과에 대한 개요를 제공한다.
{| class="wikitable"
|-
! 비교 대상 URL
! 결과
! 이유
|-
| '''<nowiki>http://www.example.com</nowiki>'''/dir/page2.html
| {{Yes|성공}}
| 프로토콜, 호스트, 포트가 동일
|-
| '''<nowiki>http://www.example.com</nowiki>'''/dir2/other.html
| {{Yes|성공}}
| 프로토콜, 호스트, 포트가 동일
|-
| '''http://'''username:password@'''<nowiki>www.example.com</nowiki>'''/dir2/other.html
| {{Yes|성공}}
| 프로토콜, 호스트, 포트가 동일
|-
| <nowiki>http://www.example.com</nowiki>:'''81'''/dir/other.html
| {{No|실패}}
| 프로토콜, 호스트가 동일하지만 포트가 다름
|-
| '''https'''://www.example.com/dir/other.html{{깨진 링크|url=http://www.example.com/dir/other.html }}
| {{No|실패}}
| 프로토콜이 다름
|-
| http://'''en.example.com'''/dir/other.html
| {{No|실패}}
| 호스트가 다름
|-
| http://'''example.com'''/dir/other.html
| {{No|실패}}
| 호스트가 다름 (정확한 일치 필요)
|-
| http://'''v2.www.example.com'''/dir/other.html
| {{No|실패}}
| 호스트가 다름 (정확한 일치 필요)
|-
| <nowiki>http://www.example.com:</nowiki>'''80'''/dir/other.html
| {{n/a|상황에 따라}}
| 포트 명시적. 브라우저의 구현에 따라 결과가 다를 수 있음.
|}

==재사용 가능한 인증을 통해 민감한 교차 출처 응답에 대한 읽기 액세스==
동일 출처 정책은 여러 출처에서 인증된 세션을 재사용하지 못하도록 보호한다. 다음 예에서는 동일 출처 정책 없이 발생할 수 있는 잠재적인 보안 위험을 보여준다. 사용자가 은행 웹사이트를 방문하고 로그아웃하지 않았다고 가정한다. 그런 다음 사용자는 은행 사이트에 데이터를 요청하는 악성 자바스크립트 코드가 있는 다른 사이트로 이동한다. 사용자가 여전히 뱅킹 사이트에 로그인되어 있기 때문에 악성 코드는 사용자가 뱅킹 사이트에서 할 수 있는 모든 작업을 수행할 수 있다. 예를 들어 사용자의 마지막 거래 목록을 가져오고 새 거래를 생성하는 등의 작업이 가능하다. 이는 월드 와이드 웹의 원래 정신에 따라 브라우저가 세션 쿠키 및 플랫폼과 같은 인증 세부 정보에 따라 태그를 지정해야 하기 때문이다. 뱅킹 사이트의 도메인을 기준으로 뱅킹 사이트에 대한 인가(Authorization) 요청 헤더의 수준 종류를 지정한다.

은행 사이트 소유자는 악성 사이트를 방문하는 사용자의 일반 브라우저가 악성 사이트에서 로드된 코드가 뱅킹 세션 쿠키 또는 플랫폼 수준 인증에 액세스하는 것을 허용하지 않을 것으로 예상한다. 자바스크립트가 뱅킹 세션 쿠키에 직접 액세스할 수 없는 것은 사실이지만 여전히 뱅킹 사이트의 세션 쿠키를 사용하여 뱅킹 사이트에 요청을 보내고 받을 수 있다. 대다수의 사용자가 호환 브라우저를 사용하기로 선택한다는 가정 하에 보안을 고려한 브라우저가 여러 출처의 응답에 대한 읽기 액세스를 거부하기 위한 요구 사항으로 동일 출처 정책이 도입되었다. 정책은 쓰기를 거부하지 않는다. 쓰기 권한 남용에 대응하려면 대상 사이트의 추가적인 [[사이트 간 요청 위조|CSRF]] 보호가 필요하다.

==동일 출처 정책 완화==
어떤 경우에는 동일 출처 정책이 너무 제한적이어서 여러 하위 도메인을 사용하는 대규모 웹사이트에 문제를 일으킬 수도 있다. 처음에는 서로 다른 도메인에 있는 문서 간에 데이터를 전달하기 위해 조각 식별자나 window.name 속성을 사용하는 등 다양한 해결 방법이 사용되었다. 최신 브라우저는 제어된 방식으로 동일 출처 정책을 완화하기 위한 여러 기술을 지원한다.

===데이터 오염===
[[넷스케이프 내비게이터]]에는 오염 검사 기능이 간략하게 포함되어 있다. 이 기능은 1997년 넷스케이프 3의 일부로 실험적으로 도입되었다. 이 기능은 기본적으로 꺼져 있지만 사용자가 활성화하면 웹 사이트에서 다른 도메인에 속한 창 및 프레임의 자바스크립트 속성을 읽으려고 시도할 수 있다. 그런 다음 브라우저는 사용자에게 문제의 액세스를 허용할지 여부를 묻는다.

===document.domain 속성===
두 개의 창(또는 프레임)에 도메인을 동일한 값으로 설정하는 스크립트가 포함된 경우 이 두 창에 대해 동일 출처 정책이 완화되고 각 창이 다른 창과 상호 작용할 수 있다. 예를 들어, orders.example.com 및 catalog.example.com에서 로드된 문서의 협력 스크립트는 document.domain 속성을 "example.com"으로 설정하여 문서의 출처가 동일한 것처럼 보이게 하고 각 문서가 다른 문서의 속성을 읽을 수 있도록 한다. 이 속성을 설정하면 포트가 암시적으로 null로 설정된다. 대부분의 브라우저는 포트 80 또는 지정되지 않은 포트와 다르게 해석한다. 브라우저에서 액세스를 허용하려면 두 페이지 모두의 document.domain 속성을 설정하면 된다.

document.domain 개념은 1996년에 출시된 넷스케이프 내비게이터 3의 일부로 도입되었다.

===교차 출처 리소스 공유===
동일 출처 정책을 완화하는 또 다른 기술은 CORS([[교차 출처 리소스 공유]])라는 이름으로 표준화되어 있다. 이 표준은 새로운 출처(Origin) 요청 헤더와 새로운 Access-Control-Allow-Origin 응답 헤더로 HTTP를 확장한다. 이를 통해 서버는 헤더를 사용하여 파일을 요청할 수 있는 출처를 명시적으로 나열하거나 와일드카드를 사용하고 모든 사이트에서 파일을 요청할 수 있도록 허용한다. 파이어폭스 3.5, 사파리 4 및 인터넷 익스플로러 10과 같은 브라우저는 이 헤더를 사용하여 동일 출처 정책에 의해 금지되었을 XMLHttpRequest를 통한 교차 출처 HTTP 요청을 허용한다.

===문서 간 메시징===
또 다른 기술인 문서 간 메시징을 사용하면 한 페이지의 스크립트가 스크립트 출처에 관계없이 다른 페이지의 스크립트에 텍스트 메시지를 전달할 수 있다. Window 객체에서 postMessage() 메서드를 호출하면 해당 창에서 "onmessage" 이벤트가 비동기적으로 발생하여 사용자 정의 이벤트 핸들러가 트리거된다. 한 페이지의 스크립트는 여전히 다른 페이지의 메서드나 변수에 직접 액세스할 수 없지만 이 메시지 전달 기술을 통해 안전하게 통신할 수 있다.

=== JSONP ===
{{본문|JSONP}}
HTML <nowiki><script></nowiki> 요소는 다른 도메인에서 콘텐츠를 검색하고 실행할 수 있으므로 페이지는 JSONP 페이로드를 반환하는 리소스를 로드하여 동일 출처 정책을 우회하고 다른 도메인에서 JSON 데이터를 수신할 수 있다. JSONP 페이로드는 사전 정의된 함수 호출로 래핑된 내부 JSON 페이로드로 구성된다. 브라우저가 스크립트 리소스를 로드하면 지정된 콜백 함수가 호출되어 래핑된 JSON 페이로드를 처리한다.

=== 웹소켓 ===
{{본문|웹소켓}}
최신 브라우저에서는 동일 출처 정책을 적용하지 않고도 스크립트가 웹소켓 주소에 연결할 수 있도록 허용한다. 그러나 웹소켓 URI가 사용되는 시기를 인식하고 연결을 요청하는 스크립트의 출처를 나타내는 Origin: 헤더를 요청에 삽입한다. 사이트 간 보안을 보장하기 위해 웹소켓 서버는 헤더 데이터를 응답 수신이 허용된 출처 허용 목록과 비교해야 한다.

==코너 케이스==
동일 출처 확인 및 관련 메커니즘의 동작은 URL(file:, data: 등)과 연관된 호스트 이름이나 포트가 명확하게 정의되지 않은 의사 프로토콜과 같은 여러 특수한 경우에 잘 정의되어 있지 않다. 이로 인해 로컬에 저장된 HTML 파일이 디스크의 다른 모든 파일에 액세스하거나 인터넷의 모든 사이트와 통신하는 일반적으로 바람직하지 않은 기능과 같은 상당히 많은 보안 문제가 발생했다.

마지막으로, DNS 리바인딩이나 서버 측 프록시와 같은 특정 유형의 공격을 사용하면 호스트 이름 확인이 부분적으로 무너질 수 있으며, 악성 웹 페이지가 "진짜" 정식 주소가 아닌 주소를 통해 사이트와 직접 상호 작용할 수 있다.  이러한 공격의 영향은 매우 구체적인 시나리오로 제한된다. 브라우저는 여전히 공격자의 사이트와 상호 작용하고 있다고 믿고 있으므로 제3자 쿠키나 기타 민감한 정보를 공격자에게 공개하지 않기 때문이다.

==공격==
동일 출처 정책이 적용되는 경우에도(교차 출처 리소스 공유로 완화되지 않음) 특정 교차 출처 공격이 수행될 수 있다. WebRTC는 피해자의 내부 IP 주소를 알아내는 데 사용될 수 있다. 교차 출처 포트에 연결을 시도하는 경우 동일 출처 정책에 따라 응답을 읽을 수 없지만 자바스크립트는 onload/onerror 이벤트가 발생하는지 확인하여 포트가 열려 있는지 또는 닫혀 있는지를 추론할 수 있다. 시간 초과가 발생한다. 이는 교차 출처 [[포트 스캔]]의 기회를 제공한다. 또한 자바스크립트 조각은 교차 사이트 누출과 같은 기술을 사용하여 브라우저에서 오랫동안 지속된 정보 누출을 활용하여 교차 출처에 대한 정보를 추론할 수 있다.

== 같이 보기 ==
* [[교차 출처 리소스 공유]]
* [[사이트 간 스크립팅]]
* [[사이트 간 요청 위조]]
* [[콘텐츠 보안 정책]]

== 각주 ==
{{각주}}

== 외부 링크 ==
* [https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy A detailed comparison of several flavors of same-origin policies]

{{전거 통제}}

[[분류:네트워크 보안]]
[[분류:컴퓨터 보안 절차]]
[[분류:컴퓨터 보안 표준]]
[[분류:웹 애플리케이션]]