Information Security

[DreamHack] Mitigation: Same Origin Policy 본문

INTERLUDE/Web Hacking

[DreamHack] Mitigation: Same Origin Policy

sohexz 2022. 1. 30. 23:06

Same Origin Policy (SOP)

이용자가 웹 서비스에 접속할 때, 브라우저는 해당 웹 서비스에서 사용하는 인증 정보인 쿠키를 HTTP 요청에 포함시켜 전달함,브라우저는 웹 리소스를 통해 간접적으로 타 사이트에 접근할 때도 인증 정보인 쿠키를 함께 전송하는 특징을 가지고 있음

->악의적인 페이지가 클라이언트의 권한을 이용해 대상 사이트에 HTTP 요청을 보내고, HTTP 응답 정보를 획득 하는 코드를 실행할 수 있음

 

클라이언트 입장에서는 가져온 데이터를 악의적인 페이지에서 읽을 수 없도록 해야 함

->브라우저의 보안 메커니즘인 동일 출처 정책 (Same Origin Policy, SOP) 

 

 

  • Same Origin Policy (SOP): 동일 출처 정책, 현재 페이지의 출처가 아닌 다른 출처로부터 온 데이터를 읽지 못하게 하는 브라우저의 보안 메커니즘
  • Same Origin: 현재 페이지와 동일한 출처
  • Cross Origin: 현재 페이지와 다른 출처
  • Cross Origin Resource Sharing (CORS): 교차 출처 리소스 공유, SOP의 제한을 받지 않고 Cross Origin의 데이터를 처리 할 수 있도록 해주는 메커니즘

 

Same Origin Policy의 오리진 (Origin) 구분 방법

오리진은 프로토콜 (Protocol, Scheme), 포트 (Port), 호스트 (Host) 로 구성됨

구성 요소가 모두 일치해야 동일한 오리진이라고 함

 

 

Same Origin Policy 실습

window.open은 새로운 창을 띄우는 함수이며, object.location.href는 객체가 가리키고 있는 URL 주소를 읽어오는 코드

 

Same Origin Policy (SOP) 데모

<!-- iframe 객체 생성 -->
<iframe src="" id="my-frame"></iframe>
<!-- Javascript 시작 -->
<script>
/* 2번째 줄의 iframe 객체를 myFrame 변수에 가져옵니다. */
let myFrame = document.getElementById('my-frame')
/* iframe 객체에 주소가 로드되는 경우 아래와 같은 코드를 실행합니다. */
myFrame.onload = () => {
    /* try ... catch 는 에러를 처리하는 로직 입니다. */
    try {
        /* 로드가 완료되면, secret-element 객체의 내용을 콘솔에 출력합니다. */
        let secretValue = myFrame.contentWindow.document.getElementById('secret-element').innerText;
        console.log({ secretValue });
    } catch(error) {
        /* 오류 발생시 콘솔에 오류 로그를 출력합니다. */
        console.log({ error });
    }
}
/* iframe객체에 Same Origin, Cross Origin 주소를 로드하는 함수 입니다. */
const loadSameOrigin = () => { myFrame.src = 'https://same-origin.com/frame.html'; }
const loadCrossOrigin = () => { myFrame.src = 'https://cross-origin.com/frame.html'; }
</script>
<!--
버튼 2개 생성 (Same Origin 버튼, Cross Origin 버튼)
-->
<button onclick=loadSameOrigin()>Same Origin</button><br>
<button onclick=loadCrossOrigin()>Cross Origin</button>
<!--
frame.html의 코드가 아래와 같습니다.
secret-element라는 id를 가진 div 객체 안에 treasure라고 하는 비밀 값을 넣어두었습니다.
-->
<div id="secret-element">treasure</div>

 

Same Origin Policy 제한 완화

브라우저가 이러한 SOP에 구애 받지 않고 외부 출처에 대한 접근을 허용해주는 경우가 존재함

이미지나 자바스크립트, CSS 등의 리소스를 불러오는 <img>, <style>, <script> 등의 태그는 SOP의 영향을 받지 않음

 

웹 서비스에서 동일 출처 정책인 SOP를 완화하여 다른 출처의 데이터를 처리 해야 하는 경우도 있음

 

자원을 공유하기 위해 사용할 수 있는 공유 방법을 교차 출처 리소스 공유 (Cross Origin Resource Sharing, CORS)라고 함

교차 출처의 자원을 공유하는 방법은 CORS와 관련된 HTTP 헤더를 추가하여 전송하는 방법을 사용함

 

Cross Origin Resource Sharing (CORS)

HTTP 헤더에 기반하여 Cross Origin 간에 리소스를 공유하는 방법

발신측에서 CORS 헤더를 설정해 요청하면, 수신측에서 헤더를 구분해 정해진 규칙에 맞게 데이터를 가져갈 수 있도록 설정

 

CORS preflight : 수신측에 웹 리소스를 요청해도 되는지 질의하는 과정

 

응답 결과

 

JSON with Padding (JSONP)

JSONP 방식은 SOP에 구애 받지 않고 외부 출처에 대해 접근을 허용하는 특징을 이용해 <script> 태그로 Cross Origin의 데이터를 불러옴

 <script> 태그 내에서는 데이터를 자바스크립트의 코드로 인식하기 때문에 Callback 함수를 활용해야 함

 Cross Origin에 요청할 때 callback 파라미터에 어떤 함수로 받아오는 데이터를 핸들링할지 넘겨주면, 대상 서버는 전달된 Callback으로 데이터를 감싸 응답함

 

 

Cross Origin에서는 응답할 데이터를 myCallback 함수의 인자로 전달될 수 있도록 myCallback으로 감싸 Javascript 코드를 반환해줌

반환된 코드는 요청측에서 실행되기 때문에 3~6번 줄에서 정의된 myCallback 함수가 전달된 데이터를 읽을 수 있음

 

But, JSONP는 CORS가 생기기 전에 사용하던 방법으로 현재는 거의 사용하지 않는 추세이기 때문에, 새롭게 코드를 작성할 때에는 CORS를 사용해야 함

'INTERLUDE > Web Hacking' 카테고리의 다른 글

[DreamHack] XSS  (0) 2022.02.13
[DreamHack] ClientSide: XSS  (0) 2022.02.13
[DreamHack] session-basic  (0) 2022.01.30
[DreamHack] cookie  (0) 2022.01.23
[DreamHack] STAGE3 - Cookie & Session  (0) 2022.01.23