Djangoのセキュリティ
このドキュメントは、Djangoのセキュリティ機能の概要です。 Djangoを利用したサイトを保護するためのアドバイスが含まれています。
クロスサイトスクリプティング(XSS)保護
XSS攻撃により、ユーザーはクライアント側のスクリプトを他のユーザーのブラウザに挿入できます。 これは通常、悪意のあるスクリプトをデータベースに保存し、そこで取得して他のユーザーに表示するか、ユーザーにリンクをクリックさせて、攻撃者のJavaScriptをユーザーのブラウザで実行させることで実現されます。 ただし、XSS攻撃は、ページに含める前にデータが十分にサニタイズされていない場合は常に、CookieやWebサービスなどの信頼できないデータソースから発生する可能性があります。
Djangoテンプレートを使用すると、XSS攻撃の大部分から保護されます。 ただし、それが提供する保護とその制限を理解することが重要です。
Djangoテンプレートは、HTMLにとって特に危険な特定の文字をエスケープします。 これはほとんどの悪意のある入力からユーザーを保護しますが、完全に絶対確実というわけではありません。 たとえば、次のものは保護されません。
<style class={{ var }}>...</style>
var
が'class1 onmouseover=javascript:func()'
に設定されている場合、ブラウザーが不完全なHTMLをレンダリングする方法によっては、JavaScriptが不正に実行される可能性があります。 (属性値を引用すると、このケースが修正されます。)
is_safe
をカスタムテンプレートタグ、:tfilter: `safe` テンプレートタグ、 mark_safe と一緒に使用する場合、および自動エスケープを有効にする場合も、特に注意する必要があります。オフ。
さらに、テンプレートシステムを使用してHTML以外のものを出力している場合は、エスケープが必要な完全に別個の文字と単語が存在する可能性があります。
また、データベースにHTMLを保存するとき、特にそのHTMLを取得して表示するときは、十分に注意する必要があります。
クロスサイトリクエストフォージェリ(CSRF)保護
CSRF攻撃により、悪意のあるユーザーは、そのユーザーの知らないうちに同意なしに、別のユーザーの資格情報を使用してアクションを実行できます。
Djangoには、ほとんどの種類のCSRF攻撃に対する保護機能が組み込まれており、を有効にして、必要に応じてを使用します。 ただし、他の緩和手法と同様に、制限があります。 たとえば、CSRFモジュールをグローバルにまたは特定のビューに対して無効にすることができます。 自分が何をしているのかを知っている場合にのみ、これを行う必要があります。 サイトに管理外のサブドメインがある場合は、他にも制限があります。
CSRF保護は各POSTリクエストでシークレットをチェックすることで機能します。 これにより、悪意のあるユーザーがフォームPOSTをWebサイトに「再生」して、別のログインユーザーに無意識のうちにそのフォームを送信させることができなくなります。 悪意のあるユーザーは、(Cookieを使用して)ユーザー固有のシークレットを知っている必要があります。
HTTPS を使用してデプロイすると、CsrfViewMiddleware
は、HTTPリファラーヘッダーが同じオリジン(サブドメインとポートを含む)のURLに設定されていることを確認します。 HTTPSは追加のセキュリティを提供するため、安全でない接続要求を転送し、サポートされているブラウザにHSTSを使用することにより、接続でHTTPSを使用できるようにすることが不可欠です。
どうしても必要な場合を除いて、csrf_exempt
デコレータでビューをマークする場合は十分に注意してください。
SQLインジェクション保護
SQLインジェクションは、悪意のあるユーザーがデータベース上で任意のSQLコードを実行できる攻撃の一種です。 これにより、レコードが削除されたり、データが漏洩したりする可能性があります。
Djangoのクエリセットは、クエリがクエリのパラメータ化を使用して構築されているため、SQLインジェクションから保護されています。 クエリのSQLコードは、クエリのパラメータとは別に定義されます。 パラメータはユーザーが提供する可能性があり、したがって安全ではないため、基盤となるデータベースドライバによってエスケープされます。
Djangoはまた、開発者に生のクエリを記述したり、カスタムSQL を実行したりする能力を与えます。 これらの機能は慎重に使用する必要があり、ユーザーが制御できるパラメーターを適切にエスケープするように常に注意する必要があります。 また、 extra()および RawSQL を使用する場合は、注意が必要です。
クリックジャッキング保護
クリックジャッキングは、悪意のあるサイトが別のサイトをフレームにラップするタイプの攻撃です。 この攻撃により、疑いを持たないユーザーがだまされて、ターゲットサイトで意図しないアクションを実行する可能性があります。
Djangoにはクリックジャッキング保護が X-Frame-Optionsミドルウェアの形式で含まれており、サポートしているブラウザーでサイトがフレーム内にレンダリングされるのを防ぐことができます。 ビューごとに保護を無効にしたり、送信される正確なヘッダー値を構成したりすることができます。
ミドルウェアは、サードパーティのサイトによってページをフレームでラップする必要がないサイト、またはサイトの小さなセクションでのみそれを許可する必要があるサイトに強くお勧めします。
SSL / HTTPS
HTTPSの背後にサイトを展開することは、セキュリティにとって常に優れています。 これがないと、悪意のあるネットワークユーザーが認証資格情報やクライアントとサーバー間で転送されるその他の情報を盗聴し、場合によってはアクティブネットワーク攻撃者がどちらの方向に送信されるデータも変更する可能性があります。
HTTPSが提供する保護が必要で、サーバーでそれを有効にしている場合は、いくつかの追加手順が必要になる場合があります。
必要に応じて、:setting: `SECURE_PROXY_SSL_HEADER` を設定し、そこでの警告を完全に理解していることを確認してください。 これを怠ると、CSRFの脆弱性が発生する可能性があり、正しく実行しないと危険な場合もあります。
:setting: `SECURE_SSL_REDIRECT` を
True
に設定して、HTTP経由のリクエストがHTTPSにリダイレクトされるようにします。:setting: `SECURE_PROXY_SSL_HEADER` の下の警告に注意してください。 リバースプロキシの場合、HTTPSへのリダイレクトを実行するようにメインWebサーバーを構成する方が簡単または安全な場合があります。
「安全な」Cookieを使用します。
ブラウザが最初にHTTP経由で接続する場合(ほとんどのブラウザのデフォルト)、既存のCookieが漏洩する可能性があります。 このため、:setting: `SESSION_COOKIE_SECURE` および:setting:` CSRF_COOKIE_SECURE` の設定を
True
に設定する必要があります。 これは、HTTPS接続を介してのみこれらのCookieを送信するようにブラウザに指示します。 これは、セッションがHTTPを介して機能しないことを意味し、CSRF保護により、POSTデータがHTTPを介して受け入れられないことに注意してください(すべてのHTTPトラフィックをHTTPSにリダイレクトする場合は問題ありません)。HTTP Strict Transport Security (HSTS)を使用する
HSTSは、特定のサイトへの今後のすべての接続で常にHTTPSを使用する必要があることをブラウザーに通知するHTTPヘッダーです。 HTTP経由でHTTPSにリクエストをリダイレクトすることと組み合わせると、接続が1回成功した場合に限り、接続は常にSSLの追加のセキュリティを享受できます。 HSTSは、:setting: `SECURE_HSTS_SECONDS` 、:setting:` SECURE_HSTS_INCLUDE_SUBDOMAINS` 、および:setting: `SECURE_HSTS_PRELOAD` で構成するか、Web上で構成できます。サーバ。
ホストヘッダーの検証
Djangoは、クライアントから提供されたHost
ヘッダーを使用して、特定の場合にURLを作成します。 これらの値はクロスサイトスクリプティング攻撃を防ぐためにサニタイズされますが、偽のHost
値は、クロスサイトリクエストフォージェリ、キャッシュポイズニング攻撃、および電子メール内のポイズニングリンクに使用できます。
一見安全に見えるWebサーバー構成でさえ、偽のHost
ヘッダーの影響を受けやすいため、Djangoは[X196X] ヘッダーを djangoの:setting: `ALLOWED_HOSTS` 設定に対して検証します。 .http.HttpRequest.get_host()メソッド。
この検証は、 get_host()を介してのみ適用されます。 コードがrequest.META
からHost
ヘッダーに直接アクセスする場合、このセキュリティ保護をバイパスしています。
詳細については、:setting: `ALLOWED_HOSTS` の完全なドキュメントを参照してください。
警告
このドキュメントの以前のバージョンでは、着信HTTP Host
ヘッダーを確実に検証するようにWebサーバーを構成することを推奨していました。 これは依然として推奨されていますが、多くの一般的なWebサーバーでは、Host
ヘッダーを検証しているように見える構成では実際には検証されない場合があります。 たとえば、ServerName
が設定されたデフォルト以外の仮想ホストからDjangoサイトが提供されるようにApacheが構成されている場合でも、HTTPリクエストがこの仮想ホストと一致して偽の[ X222X] ヘッダー。 したがって、Djangoでは、Webサーバーの構成に依存するのではなく、:setting: `ALLOWED_HOSTS` を明示的に設定する必要があります。
さらに、Djangoでは、構成で必要な場合、X-Forwarded-Host
ヘッダーのサポートを明示的に有効にする必要があります(:setting: `USE_X_FORWARDED_HOST` 設定を介して)。
リファラーポリシー
ブラウザは、Referer
ヘッダーを使用して、ユーザーがサイトにアクセスした方法に関する情報をサイトに送信します。 リファラーポリシーを設定することで、ユーザーのプライバシーを保護し、Referer
ヘッダーが設定される状況を制限することができます。 詳細については、セキュリティミドルウェアリファレンスのリファラーポリシーのセクションを参照してください。
セッションセキュリティ
CSRFの制限と同様に、信頼できないユーザーがサブドメインにアクセスできないようにサイトをデプロイする必要がありますが、 django.contrib.sessions にも制限があります。 詳細については、セキュリティに関するセッショントピックガイドセクションを参照してください。
ユーザーがアップロードしたコンテンツ
サイトでファイルのアップロードを受け入れる場合は、サービス拒否(DOS)攻撃を防ぐために、Webサーバー構成でこれらのアップロードを適切なサイズに制限することを強くお勧めします。 Apacheでは、これは LimitRequestBody ディレクティブを使用して簡単に設定できます。
独自の静的ファイルを提供している場合は、静的ファイルをコードとして実行するApacheの
mod_php
などのハンドラーが無効になっていることを確認してください。 特別に細工されたファイルをアップロードしてリクエストすることにより、ユーザーが任意のコードを実行できないようにする必要があります。Djangoのメディアアップロード処理は、そのメディアがセキュリティのベストプラクティスに従わない方法で提供される場合、いくつかの脆弱性をもたらします。 具体的には、HTMLファイルに有効なPNGヘッダーと、それに続く悪意のあるHTMLが含まれている場合、そのファイルを画像としてアップロードできます。 このファイルは、Djangoが ImageField 画像処理(枕)に使用するライブラリの検証に合格します。 その後、このファイルをユーザーに表示すると、Webサーバーの種類と構成によってはHTMLとして表示される場合があります。
ユーザーがアップロードしたすべてのファイルコンテンツを安全に検証するための防弾技術ソリューションはフレームワークレベルには存在しませんが、これらの攻撃を軽減するために実行できる他の手順がいくつかあります。
あるクラスの攻撃は、ユーザーがアップロードしたコンテンツを常に別個のトップレベルドメインまたはセカンドレベルドメインから提供することで防ぐことができます。 これにより、クロスサイトスクリプティングなどの同一生成元ポリシー保護によってブロックされるエクスプロイトが防止されます。 たとえば、サイトが
example.com
で実行されている場合、usercontent-example.com
などからアップロードされたコンテンツ(:setting: `MEDIA_URL` 設定)を提供する必要があります。usercontent.example.com
のようなサブドメインからコンテンツを提供するにはではありません。これに加えて、アプリケーションは、ユーザーがアップロードしたファイルに許可されるファイル拡張子のリストを定義し、そのようなファイルのみを提供するようにWebサーバーを構成することを選択できます。
追加のセキュリティトピック
Djangoはすぐに使用できる優れたセキュリティ保護を提供しますが、アプリケーションを適切にデプロイし、Webサーバー、オペレーティングシステム、およびその他のコンポーネントのセキュリティ保護を利用することは依然として重要です。
- PythonコードがWebサーバーのルートの外にあることを確認してください。 これにより、Pythonコードが誤ってプレーンテキストとして提供される(または誤って実行される)ことがなくなります。
- ユーザーがアップロードしたファイルには注意してください。
- Djangoは、ユーザーを認証するためのリクエストを抑制しません。 認証システムに対するブルートフォース攻撃から保護するために、DjangoプラグインまたはWebサーバーモジュールをデプロイしてこれらのリクエストを抑制することを検討してください。
- :setting: `SECRET_KEY` は秘密にしてください。
- ファイアウォールを使用して、キャッシュシステムとデータベースへのアクセスを制限することをお勧めします。
- Webアプリケーションのいくつかの一般的な脆弱性を特定するOpenWeb Application Security Project(OWASP) Top 10 list をご覧ください。 Djangoにはいくつかの問題に対処するためのツールがありますが、プロジェクトの設計では他の問題を考慮する必要があります。
- Mozillaは、 Webセキュリティに関するさまざまなトピックについて説明しています。 彼らのページには、あらゆるシステムに適用されるセキュリティ原則も含まれています。