クリックジャッキング対策の迂回方法を試してみた

クリックジャッキング対策で推奨されるのはX-FRAME-OPTIONSの使用ですが、他にもJavaScriptによる対策があったりします。
しかし、IPAの資料を見ると、どうやらJavaScriptによる対策は迂回方法があるようです。どんな迂回方法があるのか興味がわいたので、試してみました。なお、クリックジャッキング攻撃とは何か?は、徳丸さんのブログなどを見るとよいと思います。

ここでは、下記のJavaScriptによるクリックジャッキング対策を迂回する方法の検証結果を紹介します。

<script>
	if(window.top !== window.self){
		window.top.location = window.self.location;
	}
</script>

上記の対策コードは、JavaScriptの実行かwindow.top.locationの書き換えを無効にすれば迂回できそうです。
探すといくつか迂回方法の情報が見つかります。今回試した迂回方法は下記2つです。

  1. iframe要素のsandbox属性を利用した迂回
  2. ステータスコード204を利用した迂回

検証方法

まず、JavaScriptによる対策を実施したやられサイトと攻撃者が用意した罠サイトを用意します。
次に、罠サイトの設定を変更し、罠サイトからiframeでやられサイトを表示します(下図はイメージ)。


罠サイトの設定は、下記3パターンです。

  1. 特に設定なし
  2. 迂回方法1を実施
  3. 迂回方法2を実施

検証結果

パターン1[特に設定なし]
  • やられサイトに記述したJavaScriptが実行され、強制的にwindow.topにやられサイトが表示される

JavaScriptの対策が有効なため、罠サイトにやられサイトを表示することができませんでした。

パターン2[迂回方法1を実施]
  • やられサイトに記述したJavaScriptが実行されず、罠サイトにiframeでやられサイトを表示することができる
  • やられサイトに記述したJavaScriptは実行されるが、強制的にwindow.topにやられサイトを表示することはできない

多くのブラウザで上記の結果になりました。
迂回するためのコードは下記の通りです。これを罠サイトに記述します。

//やられサイトに記述したJavaScriptが実行されず、罠サイトにiframeでやられサイトを表示することができる
<iframe id="target" sandbox="allow-forms" src="やられサイトのURL"></iframe>
//やられサイトに記述したJavaScriptは実行されるが、強制的にwindow.topにやられサイトを表示することはできない
<iframe id="target" sandbox="allow-forms allow-scripts" src="やられサイトのURL"></iframe>

下記が検証したブラウザおよび結果の一覧です。

ブラウザ バージョン 迂回成功
IE 9
10
×
Firefox*1 20.0
20.0(Android)

Chrome 26.0.1410.43 m
18.0.1025469(Android)

Opera 12.15
Mobile 12.1(Android)
×
×
Safari 5.1.7
6.1.3(iOS)

iframe要素のsandbox属性をサポートするブラウザにおいて有効な迂回方法です。sandbox属性はiframeで読み込むコンテンツに対して様々な制限を課すことができ、例えば、JavaScriptやフォームのsubmitを無効にしたり、window.topの書き換えを禁止したりすることが可能です。また、allow-xxxで制限を緩めることも可能です。

クリックジャッキング攻撃は、クリックだけで設定変更できるページにおいて、利用者を視覚的に騙してsubmitボタンまで押させる攻撃です。そのため攻撃者は、攻撃の邪魔になる制限は排除し、JavaScriptによる対策は無効化するようにsandbox属性値を設定すると思われます。sandbox属性について詳しくはW3Cの情報を確認するのがよいと思います。が、カラフル過ぎて読む気が...

なお、下記のような対策を実施しており、かつJavaScriptを有効にしないと(クリック操作だけでは)フォームのsubmitができないサイトでは、JavaScriptによる対策は迂回されないと思われますが、素直にX-FRAME-OPTIONSを使ったほうがよいですよね。

<script>
	if(window.top !== window.self){
		document.body.innerHTML="hoge";
	}
</script>
パターン3[迂回方法2を実施]
  • やられサイトに記述したJavaScriptは実行されるが、強制的にwindow.topにやられサイトを表示することはできない

デスクトップ向けのChromeのみ、上記の結果になりました。他のブラウザは、強制的にwindow.topにやられサイトが表示されました。
迂回するためのコードは下記の通りです。これを罠サイトに記述します。

<script>
    var prevent_bust = 0;  
    window.onbeforeunload = function(){ prevent_bust++ };  
    setInterval(function(){  
      if (prevent_bust > 0) {  
        prevent_bust -= 2;
        window.top.location = './204.php';
      }
    }, 1);
</script>

204.phpのコードは下記の通りです。

<?php
header("HTTP/1.0 204 No Content");
?>

下記が検証したブラウザおよび結果の一覧です。

ブラウザ バージョン 迂回成功
IE 9
10
×
×
Firefox 20.0
20.0(Android)
×
×
Chrome 26.0.1410.43 m
18.0.1025469(Android)

×
Opera 12.15
Mobile 12.1(Android)
×
×
Safari 5.1.7
6.1.3(iOS)
×
×

かなりアドホックな迂回方法です。RFC2616によると、HTTPステータスコード204はレスポンスにメッセージボディを含めてはならず、ユーザエージェントのdocument viewを変更すべきではないそうです。つまり、ブラウザは画面の更新をしない(はず)。上記の迂回コードは、やられサイト側のwindow.top.locationの書き換えが発生した直後に、window.top.locationを204のステータスコードを返すURLに変更し、あわよくばやられサイト側のwindow.top.locationの書き換えを無効化しようとしています。が、成功したのはデスクトップ向けのChromeだけでした。しかも、Chromeにおいても100%の成功率ではありませんでした。やられサイトの情報がブラウザ上に中途半端に表示される場合もあり、成功可否にはインターネット回線やPCの処理速度など様々な要素が絡んでいそうだと感じました。

まとめ

いろいろと書きましたが、クリックジャッキング攻撃は、JavaScriptによる対策は迂回される可能性があるため、X-FRAME-OPTIONSを使って対策した方がよいというお話です。 ちなみにX-FRAME-OPTIONSは、metaタグによる指定では有効にならないので注意です。指定方法は、IPAの『クリックジャッキング』に関するレポートなどを参照するとよいと思います。

ツッコミ等ありましたら指摘ください。Twitterも同じIDです。

*1:window.topの書き換え制限は実装されていない模様