Same-origin Policy (SOP)

dogyeong·2021년 7월 22일
0

웹 보안

목록 보기
1/4

SOP에 대해 공부하며 정리한 글입니다. 자세한 내용은 레퍼런스의 링크들을 읽는 것이 좋습니다.

SOP란?

문서 또는 스크립트가 다른 origin과 통신하는 것을 제한하는 매커니즘

SOP의 필요성

인터넷상의 악의적인 사이트들의 공격들을 막는데 도움이 된다.

예를 들어 악의적인 웹사이트에 다음과 같은 스크립트가 있다고 가정하면 접속한 사용자의 모든 메일을 얻을 수도 있는 것이다. (CSRF, XSS, Clickjacking등의 공격)

<!-- 이런 공격을 CSRF라고 합니다 -->
<!-- 실제로 이런 api는 없습니다! -->
<script>
	fetch('https://gmail.com/api/all-mail')
		.then((res) => sendToEvilServer(res));
</script>

origin의 정의

origin은 프로토콜, 호스트, 포트를 합친 것이다. 셋 중에 하나라도 다르면 다른 origin으로 취급된다.

예시

origin의 상속

url이 about:black, :javascript인 문서의 스크립트는 상위 문서의 origin을 상속받는다.

예시

노션 페이지의 개발자도구 콘솔에서 window.open()을 입력하여 빈 페이지를 새 창으로 띄운다.
새 창에서 url과 origin을 확인해보면 노션의 origin을 그대로 사용하는 것을 확인할 수 있다.

Internet Explorer에서 예외사항

  1. 인트라넷처럼 신뢰할 수 있는 환경에서는 SOP를 적용하지 않는다 (어떻게?)
  2. 포트번호는 origin을 체크할 때 포함되지 않는다. 즉, 다른 포트로 요청할 수 있다.

origin 변경

document.domain에 값을 할당하는 방식으로 약간의 제한과 함께 사용할 수 있지만, 보안적인 이유로 사용하지 않는다.

Cross-origin 접근 처리

"그러면 SOP는 모든 cross-origin 요청을 막는 것인가? 지금까지 잘 다른 사이트의 리소스를 사용했는데?" 라고 말할 수 있다.

사실 그렇지는 않다. 역사적 사정이 있기 때문인지 몇몇 HTML태그들은 SOP의 제한을 받지 않는다.

SOP는 요청을 세 가지 카테고리로 나누고 각각 다르게 처리한다.

  1. 쓰기: 일반적으로 허용한다. 일부 HTTP요청은 preflight가 필요하다
    (CORS에서 등장하는 preflight)
    - 링크, 리다이렉트, 폼 제출
    - <a>
    - <form> 으로 다른 origin에 데이터를 쓰는 작업
  2. 임베딩: 일반적으로 허용한다.
    • <script src="..."></script>
    • <link rel="stylesheet" href="…">
    • <img>, <video>, <audio>, <object>, <embed>
    • @font-face
    • <iframe>
  3. 읽기: 일반적으로 허용하지 않는다.
    • 보통 js 코드로 접근하는 행위들이 해당된다.
      • js로 iframe내의 document에 접근
      • js로 canvas내에 다른 origin의 이미지를 불러오는 작업
      • js로 다른 리소스를 fetch하는 작업

cross-origin 요청을 허용 또는 차단하는 방법

필요에 따라서 SOP의 제한을 허용해주거나 SOP에 적용되지 않는 제한을 추가하면 좋을 때가 있다.

이런 필요에 의해 등장한 개념이 대표적으로 CORS와 CSP이다.

  • 허용
    • Cross-Origin Resource Sharing(CORS)
    • JSONP (CORS가 등장하기 전에 사용하던 우회방법)
  • 차단
    • CSP(Content Security Policy)
    • CSRF token

Cross-origin script API 접근

iframe, popup처럼 서로 다른 문서가 서로 직접 참조할 수 있는 경우, 두 문서의 origin이 다르면 다른 문서의 window, location객체에 사용할 수 있는 API가 제한된다.

  • cross-origin 상태의 문서간 통신을 위해서는 postMessage()를 사용하는 것이 좋다.

Cross-origin data storage 접근

다른 origin의 저장된 데이터(WebStorage, IndexdeDB)는 읽을 수 없다.

Reference

profile
Engineer

0개의 댓글