Notice
Recent Posts
Recent Comments
Link
관리 메뉴

oioi

X-Frame-options 우회 방법 본문

카테고리 없음

X-Frame-options 우회 방법

oio! 2018. 4. 19. 19:04

X-Frame-Options 

X-Frame-Options 헤더는 보안목적으로 외부에서 FrameSet이나 iframe 요청에 의한 ClickJacking 공격에 대한 보호를 위해 사용하게 됩니다.

허용하지 않는 페이지에서 frame을 요청할 경우 사용하는 옵션에 따라서 비허용할 것인지, 허용할 것인지 결정 할 수 있게됩니다.


X-Frame-Options 옵션 값

  • X-Frame-Options: DENY (프레임 비허용)
  • X-Frame-Options: SAMEORIGIN (동일한 origin만 허용)
  • X-Frame-Options: ALLOW FROM uri (지정한 origin만 허용) 


아래 이미지에서 네이버 응답 헤더는 "X-Frame-Options: SAMEORIGIN" 으로 설정되어 있는 것을 확인 할 수 있습니다.

X-Frame-options이 설정되어 있기 때문에 네이버를 iframe 태그로 요청하게 되면 아래 처럼 아무것도 표시가 되지 않습니다.

이런 X-Frame-Options 을 우회하기 위해서 YQL을 사용할 수 있습니다.

YQL (Yahoo! Query Language)은 야후에서 만든 sql과 유사한 검색어 언어입니다. YQL API를 사용하여 사이트를 요청하고 응답값을 받아와서 X-Frame-Options을 우회 할 수있습니다.


YQL 사용 과정

  1. YQL에서 iframe URL 요청 (function loadURL )
  2. YQL (함수 getData )에서 HTML 데이터 가져 오기
  3. YQL을 사용하여 iframe에 <base link> 및 <script> 로드 링크를 추가합니다.
  4. 이 HTML을 빈 <iframe> 삽입하십시오 ( loadHTML 함수).

- xframetest.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<html>
<head>
<style>
/* iframe 배율 조절 */
iframe {
    zoom: 0.5; -moz-transform: scale(0.5); -moz-transform-origin: 0 0;
}
 
</style>
 
</head>
<body>
 
<form action="xframetest.php" method="get">
URL : <input type="text" name="url" />
<input type="submit" />
</form>
<p>
Output : <?php echo $_GET["url"]; ?><br>
<iframe src='<?php echo $_GET["url"]; ?>' width="1200" height="700" style="zoom" scrolling="no"></iframe>
</p>
 
<!-- X-Frame-Options 우회 -->
<script type="text/javascript">
var iframe = document.getElementsByTagName('iframe')[0];
var url = iframe.src;
var getData = function (data) {
    if (data && data.query && data.query.results && data.query.results.resources && data.query.results.resources.content && data.query.results.resources.status == 200) loadHTML(data.query.results.resources.content);
    else if (data && data.error && data.error.description) loadHTML(data.error.description);
    else loadHTML('Error: Cannot load ' + url);
};
var loadURL = function (src) {
    url = src;
    var script = document.createElement('script');
    script.src = 'http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20data.headers%20where%20url%3D%22' + encodeURIComponent(url) + '%22&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=getData';
    document.body.appendChild(script);
};
var loadHTML = function (html) {
    iframe.src = 'about:blank';
    iframe.contentWindow.document.open();
    iframe.contentWindow.document.write(html.replace(/<head>/i, '<head><base href="' + url + '"><scr' + 'ipt>document.addEventListener("click", function(e) { if(e.target && e.target.nodeName == "A") { e.preventDefault(); parent.loadURL(e.target.href); } });</scr' + 'ipt>'));
    iframe.contentWindow.document.close();
}
 
loadURL(iframe.src);
</script>
</body>
</html>
cs


해당 코드로 테스트를 해보면 x-frame-options이 설정된 네이버도 헤더를 우회하여 iframe 태그로 로드할 수 있는 것을 확인할 수 있습니다.



* YQL을 사용하는 방법은 브라우저 별로 동작하지 않을 수 있습니다.

IE11 : 불가능

Safari : 불가능

Chrome : 66.0.3359.181 가능

FireFox : 56.0 가능



Comments