2023. 2. 8. 15:03ㆍ보안/웹해킹
SOP(Same Origin Policy)
SOP란 동일한 오리진에서만 요청한 데이터를 조회할 수 있게 제한하는 웹 보안 정책이다.
XSS와 같은 공격이 사용자의 권한을 이용해 서버에 요청을 보내는 경우, 현재 경로가 아닌 공격자가 알고 싶은 다른 페이지의 데이터를 요청하는 등 악의적인 요청이 전송된다. 이를 이용하여 현재의 오리진과 다른 오리진이 데이터를 읽을 수 없게 제한하는 것이다.
Origin
오리진은 프로토콜(Protocol or Schema), 호스트(Host), 포트(Port)로 구성된다.
다음의 url에서 같은 오리진과 크로스 오리진을 구분해보자.
- 같은 오리진 : 경로(path)만 다른 경우
https://sec-sec-burger.tistory.com/newpost:7080 - 다른 오리진 : 프로토콜, 호스트, 포트가 다른 경우
http://sec-sec-burger.tistory.com:7080
https://sec-sec-burger.tistory.com:9999
https://fake-sec-sec-burger.tistory.com:7080
SOP 실습
간단한 예제를 통해 SOP가 어떻게 적용되는지 살펴보자.
다음은 내 블로그와 같은 origin을 가진 url을 새로 열어 쿠키 데이터를 읽는 코드이다.
sameOrigin = window.open('https://sec-sec-burger.tistory.com');
console.log(sameOrigin.location.href);
다음은 내 블로그와 다른 origin을 가진 url을 열어 쿠키 데이터를 읽는 코드이다.
crossOrigin = window.open("https://naver.com");
console.log(crossOrigin.document.cookie);
새로 연 페이지가 같은 origin인 경우에는 해당 페이지의 cookie를 잘 읽어온다.
하지만 새로 연 페이지가 다른 origin인 경우에는 아래와 같이 오류 메시지가 나오며
새로 연 페이지의 데이터를 가져올 수 없다.
SOP 가 예외적으로 완화되는 경우
예외적으로 origin이 달라도 접근을 허용해주는 경우가 몇 가지 있다. 대표적으로 아래와 같은 경우다.
임베딩 된 Cross Origin
<script>
태그를 사용한 자바스크립트- CSS 등의 리소스를 불러오는 태그 ex.
<img>
,<video>
,<audio>
,@font-face
로 적용한 폰트 리소스
CSS의 경우, Content-Type 헤더에 유의해야 한다. cross origin에서 CSS 리소스를 요청하면서 MIME type이 이상하거나 요청하는 리소스가 유효한 CSS 구조로 시작하지 않는 경우에는 브라우저에서 스타일시트 로드를 차단한다. <object>
와<embed>
태그로 불러오는 외부 객체<iframe>
태그로 임베딩 된 모든 것
이 경우, cross-origin framing을 방지하기 위해 X-Frame-Options 헤더를 사용해서 iframe 내에 페이지를 로딩하는 것을 제어할 수 있다.
CORS(Cross Origin Resource Sharing)
교차 출처 리소스 공유란, HTTP 헤더에 기반하여 다른 오리진에서도 데이터에 접근할 수 있도록 하는 SOP 완화 방법이다. 데이터를 요청하는 쪽에서 CORS 헤더를 설정해 데이터를 요청하면 수신 쪽에서 헤더를 보고 정의된 설정에 따라 데이터를 허용하거나 거부한다.이렇게 설정하는 CORS 헤더를 cors-preflight
라고 한다.
아래는 드림핵에 있는 예제와 그 결과다.
xhr = new XMLHttpRequest();
xhr.open('POST', 'https://theori.io/whoami');
xhr.withCredentials = true;
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send("{'data':'WhoAmI'}");
cors preflight는 OPTIONS
헤더를 사용하며, Access-Control-Request-Method
와 Access-Control-Request-Header
를 통해 추가적으로 허용되는 메소드와 헤더를 질의한다.
cors preflight는 요청 시 브라우저에서 자동으로 설정돼서 따로 설정할 필요는 없다.
수신 측은 응답으로 허용되는 메소드와 헤더를 돌려준다. 거부하는 경우 아래와 같이 access control check를 실패했다는 에러가 뜬다 ㅜ
티스토리를 대상으로 허용 메시지를 받아보자! 응 어림도 없지~ 안됐다. webhook.site에서도 해봤지만 거부의 응답이 왔다.. 커스텀하려면 유료 업그레드해야해서 ㅋㅋ
어쩔 수 없이 응답은 코드로 대체하겠다.. ㅜㅜ
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://dreamhack.io
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type
- Access-Control-Allow-Origin: 이 헤더에 설정된 origin에서만 데이터 허용
- Access-Control-Allow-Methods: 이 헤더에 설정된 메소드들 허용
- Access-Control-Allow-Credentials: 쿠키 사용 여부(true or false)
- Access-Control-Allow-Headers: 이 헤더에 설정된 헤더 허용
정리해보면 위 응답은 https://dreamhack.io origin에서 들어오는 요청에 한해 POST, GET, OPTIONS 메소드와 Content-Type 헤더, 쿠키 사용을 허용한다는 뜻이다.
오늘은 SOP와 CORS 에 대해 알아봤다!
Reference
https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
Same-origin policy - Web security | MDN
The same-origin policy is a critical security mechanism that restricts how a document or script loaded by one origin can interact with a resource from another origin.
developer.mozilla.org
로그인 | Dreamhack
dreamhack.io