クリックジャッキング対策

クリックジャッキングミドルウェアとデコレータは、簡単に使える クリックジャッキング 攻撃に対する防御を提供します。このタイプの攻撃は、 悪意のあるサイトがユーザをだまし、隠された frame や iframe にロードした別サイト の要素をクリックさせることで起こります。

クリックジャッキングの例

あるオンラインストアのサイトに、ログインユーザが「今すぐ購入」ボタンを押すことで 商品を買えるようなページがあるとしましょう。あるユーザが利便性のためログインし 続けることを選択していたとします。そして攻撃者が彼ら自身のサイトのページに 「私はポニーが好きです」ボタンを作り、さらに透明な iframe に先ほどのストアの ページをロードして『「今すぐ購入」ボタンが彼らの「私はポニーが好きです」ボタンを 真上に来るように』重ねたとします。もしそのユーザが攻撃者のサイトを訪ねて 「私はポニーが好きです」ボタンをクリックしてしまうと、無意識に「今すぐ購入」 ボタンをクリックすることとなり、身に覚えの無い品物を購入することに なってしまいます。

クリックジャッキングを防止する

モダンなブラウザは、frame や iframe の中にあるリソースをロードして良いかどうかを 示す X-Frame-Options HTTP ヘッダの指定を尊重します。 もしサーバからのレスポンスに SAMEORIGIN という値を指定した X-Frame-Options ヘッダが含まれていた場合、ブラウザは frame 中のリソースが同一サイトに由来する 場合に限り、そのリソースをロードします。もしヘッダが DENY に設定されていた場合、どのサイトがリクエスト元であろうとブラウザは frame 中のリソースのロードを問答無用でブロックします。

Django はこのヘッダをレスポンスに含める簡単な方法をいくつか提供します:

  1. すべてのレスポンスにこのヘッダを設定するシンプルなミドルウェア
  2. そのミドルウェアの動作をオーバーライドする、または単純に特定のビューにだけ このヘッダを設定するデコレータのセット

使用方法

X-Frame-Options をすべてのレスポンスに設定する

同じ X-Frame-Options 値をサイトの全レスポンスに設定するには、 'django.middleware.clickjacking.XFrameOptionsMiddleware'MIDDLEWARE_CLASSES に設定します:

MIDDLEWARE_CLASSES = (
    ...
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ...
)

このミドルウェアは startproject が生成する設定ファイルでは 最初から有効化されています。

デフォルトでは、このミドルウェアはすべての HttpResponseX-Frame-Options ヘッダを SAMEORIGIN に設定します。もし DENY にしたい場合は X_FRAME_OPTIONS の設定を次のように設定します:

X_FRAME_OPTIONS = 'DENY'

このミドルウェアを使うにあたって、いくつかのビューでは X-Frame-Options ヘッダを設定 したくない かもしれません。そのような場合、 ビューデコレータでミドルウェアにヘッダを設定しないよう指示することができます:

from django.http import HttpResponse
from django.views.decorators.clickjacking import xframe_options_exempt

@xframe_options_exempt
def ok_to_load_in_a_frame(request):
    return HttpResponse("This page is safe to load in a frame on any site.")

X-Frame-Options をビューごとに設定する

X-Frame-Options ヘッダをビューごとに設定するために、Django は次のようなデコレータを提供しています:

from django.http import HttpResponse
from django.views.decorators.clickjacking import xframe_options_deny
from django.views.decorators.clickjacking import xframe_options_sameorigin

@xframe_options_deny
def view_one(request):
    return HttpResponse("I won't display in any frame!")

@xframe_options_sameorigin
def view_two(request):
    return HttpResponse("Display in a frame if it's from the same origin as me.")

なお、これらのデコレータはミドルウェアとともに使うことができます。 デコレータの指定は、ミドルウェアの指定よりも優先されます。

制限事項

X-Frame-Options ヘッダによるクリックジャッキング対策はモダンなブラウザに 対してのみ有効です。古いブラウザの場合はこのヘッダを無視してしまうため、 他のクリックジャッキング対策 が必要です。

X-Frame-Options をサポートするブラウザ

  • Internet Explorer 8+
  • Firefox 3.6.9+
  • Opera 10.5+
  • Safari 4+
  • Chrome 4.1+

参考情報

X-Frame-Options をサポートするブラウザの 完全な一覧