Django
セキュリティ
サーチ…
クロスサイトスクリプティング(XSS)保護
XSS攻撃は、HTML(またはJS)コードをページに挿入することで構成されます。詳細は、クロスサイトスクリプティングとは?を参照してください。
この攻撃を防ぐため、デフォルトではDjangoはテンプレート変数を渡す文字列をエスケープします。
以下の文脈を考えると、
context = {
'class_name': 'large" style="font-size:4000px',
'paragraph': (
"<script type=\"text/javascript\">alert('hello world!');</script>"),
}
<p class="{{ class_name }}">{{ paragraph }}</p>
<!-- Will be rendered as: -->
<p class="large" style="font-size: 4000px"><script>alert('hello world!');</script></p>
信頼して実際にレンダリングしたいHTMLを含む変数がある場合、明示的に安全であると言わなければなりません:
<p class="{{ class_name|safe }}">{{ paragraph }}</p>
<!-- Will be rendered as: -->
<p class="large" style="font-size: 4000px"><script>alert('hello world!');</script></p>
すべての安全な複数の変数を含むブロックがある場合、ローカルで自動エスケープを無効にすることができます:
{% autoescape off %}
<p class="{{ class_name }}">{{ paragraph }}</p>
{% endautoescape %}
<!-- Will be rendered as: -->
<p class="large" style="font-size: 4000px"><script>alert('hello world!');</script></p>
また、テンプレートの外側で文字列を安全なものとしてマークすることもできます。
from django.utils.safestring import mark_safe
context = {
'class_name': 'large" style="font-size:4000px',
'paragraph': mark_safe(
"<script type=\"text/javascript\">alert('hello world!');</script>"),
}
<p class="{{ class_name }}">{{ paragraph }}</p>
<!-- Will be rendered as: -->
<p class="large" style="font-size: 4000px"><script>alert('hello world!');</script></p>
format_html
などのDjangoユーティリティの中には、すでに安全とマークされた文字列を返すものもあります。
from django.utils.html import format_html
context = {
'var': format_html('<b>{}</b> {}', 'hello', '<i>world!</i>'),
}
<p>{{ var }}</p>
<!-- Will be rendered as -->
<p><b>hello</b> <i>world!</i></p>
クリックジャッキ保護
Clickjackingは、Webユーザーをクリックして、ユーザーがクリックしたことと違うものをクリックするという悪意のあるテクニックです。 もっと詳しく知る
クリックXFrameOptionsMiddleware
保護を有効にするには、ミドルウェアクラスにXFrameOptionsMiddleware
を追加します。あなたがそれを削除しなかった場合、これは既にそこにあるはずです。
# settings.py
MIDDLEWARE_CLASSES = [
...
'django.middleware.clickjacking.XFrameOptionsMiddleware',
...
]
このミドルウェアは、明示的に免除されていないか、既に設定されていない限り(応答に既に設定されている場合は上書きされない)、すべての回答に 'X-Frame-Options'ヘッダーを設定します。デフォルトでは「SAMEORIGIN」に設定されています。これを変更するには、 X_FRAME_OPTIONS
設定を使用します。
X_FRAME_OPTIONS = 'DENY'
ビュー単位でデフォルトの動作を上書きすることができます。
from django.utils.decorators import method_decorator
from django.views.decorators.clickjacking import (
xframe_options_exempt, xframe_options_deny, xframe_options_sameorigin,
)
xframe_options_exempt_m = method_decorator(xframe_options_exempt, name='dispatch')
@xframe_options_sameorigin
def my_view(request, *args, **kwargs):
"""Forces 'X-Frame-Options: SAMEORIGIN'."""
return HttpResponse(...)
@method_decorator(xframe_options_deny, name='dispatch')
class MyView(View):
"""Forces 'X-Frame-Options: DENY'."""
@xframe_options_exempt_m
class MyView(View):
"""Does not set 'X-Frame-Options' header when passing through the
XFrameOptionsMiddleware.
"""
クロスサイトリクエスト偽造(CSRF)保護
ワンクリック攻撃またはセッションライドとも呼ばれ、CSRFまたはXSRFと略されるクロスサイトリクエスト偽造は、Webサイトが信頼するユーザーから許可されていないコマンドが送信される、Webサイトの悪意のある攻撃の一種です。 もっと詳しく知る
CSRF保護を有効にするには、ミドルウェアクラスにCsrfViewMiddleware
を追加します。このミドルウェアはデフォルトで有効になっています。
# settings.py
MIDDLEWARE_CLASSES = [
...
'django.middleware.csrf.CsrfViewMiddleware',
...
]
このミドルウェアは、発信応答のクッキーにトークンを設定します。着信要求が安全でないメソッド( GET
、 HEAD
、 OPTIONS
、 TRACE
以外のメソッド)を使用する場合は常に、 csrfmiddlewaretoken
フォームデータまたはX-CsrfToken
ヘッダーとして送信されるトークンと一致する必要があります。これにより、要求を開始したクライアントがCookieの所有者であり、拡張(認証された)セッションでもあることが保証されます。
HTTPS
介して要求が行われると、厳密な参照元のチェックが有効になります。 HTTP_REFERER
ヘッダーが現在の要求のホストまたはCSRF_TRUSTED_ORIGINS
ホスト( 1.9の新機能 )と一致しない場合、要求は拒否されます。
POST
メソッドを使用するフォームは、CSRFトークンをテンプレートに含める必要があります。 {% csrf_token %}
テンプレートタグは非表示のフィールドを出力し、レスポンスにCookieが設定されていることを確認します:
<form method='POST'>
{% csrf_token %}
...
</form>
@csrf_exempt
デコレータを使用すると、CSRF攻撃に対して脆弱ではない個々のビューを除外することができます。
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def my_view(request, *args, **kwargs):
"""Allows unsafe methods without CSRF protection"""
return HttpResponse(...)
推奨されていませんが、多くのビューがCSRF攻撃に対して脆弱でない場合は、 CsrfViewMiddleware
を無効にすることができます。この場合、 @csrf_protect
デコレータを使用して個々のビューを保護することができます。
from django.views.decorators.csrf import csrf_protect
@csrf_protect
def my_view(request, *args, **kwargs):
"""This view is protected against CSRF attacks if the middleware is disabled"""
return HttpResponse(...)