クリックジャッキング対策¶
クリックジャッキングミドルウェアとデコレータは、 clickjacking 攻撃に対する防御を簡単に使える形で提供します。このタイプの攻撃は、悪意のあるサイトがユーザをだまし、隠された frame や iframe にロードした別サイトの要素をクリックさせることで起こります。
クリックジャッキングの例¶
あるオンラインストアのサイトに、ログインユーザが「今すぐ購入」ボタンを押すことで商品を買えるようなページがあるとしましょう。あるユーザが利便性のためログインし続けることを選択していたとします。そして攻撃者が彼ら自身のサイトのページに 「私はポニーが好きです」ボタンを作り、さらに透明な iframe に先ほどのストアのページをロードして『「今すぐ購入」ボタンが彼らの「私はポニーが好きです」ボタンを真上に来るように』重ねたとします。もしそのユーザが攻撃者のサイトを訪ねて「私はポニーが好きです」ボタンをクリックしてしまうと、無意識に「今すぐ購入」 ボタンをクリックすることとなり、身に覚えの無い品物を購入することになってしまいます。
クリックジャッキングを防止する¶
モダンブラウザでは、frame や iframe の中にあるリソースをロードして良いかどうかを示す X-Frame-Options HTTP ヘッダの指定を尊重します。もしサーバからのレスポンスに SAMEORIGIN
という値を指定した X-Frame-Options ヘッダが含まれていた場合、ブラウザは frame 中のリソースが同一サイトに由来する場合に限り、そのリソースをロードします。もしヘッダが DENY
に設定されていた場合、どのサイトがリクエスト元であろうとブラウザは frame 中のリソースのロードを問答無用でブロックします。
Django はこのヘッダをレスポンスに含めるための方法をいくつか提供します:
すべてのレスポンスにこのヘッダを設定するミドルウェア
そのミドルウェアの動作をオーバーライドする、または単純に特定のビューにだけこのヘッダを設定するデコレータのセット
X-Frame-Options
HTTP ヘッダは、まだそれがレスポンス中に存在しない場合に、ミドルウェアまたはビューのデコレータでのみ設定されます。
使用方法¶
X-Frame-Options をすべてのレスポンスに設定する¶
サイト内のすべてのレスポンスに対して同じ X-Frame-Options
値を設定するには、'django.middleware.clickjacking.XFrameOptionsMiddleware'
を MIDDLEWARE
に追加します:
MIDDLEWARE = [
...,
"django.middleware.clickjacking.XFrameOptionsMiddleware",
...,
]
このミドルウェアは、startproject
が生成する設定ファイルでは最初から有効化されています。
デフォルトでは、このミドルウェアはすべての HttpResponse
の X-Frame-Options
ヘッダを DENY
に設定します。もし他の値にしたい場合は X_FRAME_OPTIONS
を次のように設定します:
X_FRAME_OPTIONS = "SAMEORIGIN"
このミドルウェアを使うにあたって、いくつかのビューでは 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.")
注釈
フレームやiframe内でフォームを送信したり、セッションクッキーにアクセスしたい場合は、 CSRF_COOKIE_SAMESITE
や SESSION_COOKIE_SAMESITE
の設定を変更する必要があるかもしれません。
@xframe_options_exempt
デコレーターに、非同期ビュー関数をラップする機能が追加されました。
Setting 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.")
なお、これらのデコレータはミドルウェアとともに使うことができます。 デコレータの指定は、ミドルウェアの指定よりも優先されます。
@xframe_options_deny
と @xframe_options_sameorigin
デコレーターに、非同期ビュー関数をラップする機能が追加されました。
制限事項¶
The X-Frame-Options
header will only protect against clickjacking in
modern browsers.