ミドルウェア

このドキュメントでは、Djangoに付属するすべてのミドルウェアコンポーネントについて説明します。それらの使用方法や独自のミドルウェアの作成方法についての情報は、 ミドルウェア使用ガイド を参照してください。

使用できる middleware

Cache middleware

class UpdateCacheMiddleware
class FetchFromCacheMiddleware

サイト全体でキャッシュを有効にします。有効にすると、Django を利用している各ページは CACHE_MIDDLEWARE_SECONDS 設定で指定した時間だけキャッシュされます。詳しくは キャッシュのドキュメント を参照してください。

Common middleware

class CommonMiddleware

完璧主義者のためにいくつかの便利な機能を提供します。

  • DISALLOWED_USER_AGENTS 設定に含まれるユーザーエージェントのアクセスを禁止します。この設定は、コンパイルした正規表現オブジェクトのリストである必要があります。

  • APPEND_SLASH および PREPEND_WWW 設定に基づいて、URL の書き換えを実行します。

    APPEND_SLASHTrue で、与えられた URL がスラッシュで終わっていなくて、さらに URLconf に URL が見つからなければ、Django は / が最後に追加された新しい URL を作り、この新しい URL へリクエストをリダイレクトします。それ以外のときには、最初の URL を通常通りに処理します。

    たとえば、 foo.com/bar は、 foo.com/bar に対する有効な URL パタンがなく、foo.com/bar/ に対しては有効なパタンが 存在する 場合に、 foo.com/bar/ にリダイレクトされます。

    PREPEND_WWWTrue にすると、先頭に "www." がない URL は "www." で始まる同じ URL にリダイレクトされます。

    2つのオプションが意味するのは、URL を正規化するということです。これは、1つの URL には1つの、かつただ1つだけの場所を指すべきだという考えです。技術的には URL foo.com/barfoo.com/bar/ とは区別されます。実際、サーチエンジンのインデクスはこれらを区別して作成されます。よって、URL を正規化するというのがベストプラクティスなのです。

    必要に応じて、個々のビューは、 no_append_slash() デコレータを使用して、APPEND_SLASH の動作から除外できます。

    from django.views.decorators.common import no_append_slash
    
    
    @no_append_slash
    def sensitive_fbv(request, *args, **kwargs):
        """View to be excluded from APPEND_SLASH."""
        return HttpResponse()
    
  • 非ストリーミングレスポンスに対して Content-Length ヘッダを設定します。

CommonMiddleware.response_redirect_class

デフォルトは HttpResponsePermanentRedirect です。ミドルウェアが発行するリダイレクトをカスタマイズするには、 CommonMiddleware をサブクラス化し、この属性をオーバーライドします。

class BrokenLinkEmailsMiddleware

GZip middleware

class GZipMiddleware
max_random_bytes

デフォルトは 100 です。 圧縮されたレスポンスに含まれるランダムバイトの最大数を変更するには、GZipMiddleware をサブクラス化して属性をオーバーライドしてください。

注釈

セキュリティ研究者たちは、Webサイトで GZipMiddleware を含む圧縮技術が使用されると、そのサイトが多くの潜在的な攻撃にさらされる可能性があることを明らかにしました。

攻撃を軽減するために、Django は Heal The Breach (HTB) と呼ばれる技術を実装しています。攻撃の効果を軽減するため、各レスポンスに最大で 100 バイトまでのランダムなバイト (詳細は max_random_bytes を参照) を追加します。

詳細については、 BREACH paper (PDF)breachattack.com、そして Heal The Breach (HTB) paper を参照してください。

Changed in Django 4.2:

BREACH 攻撃に対する緩和策が追加されました。

django.middleware.gzip.GZipMiddleware は、GZip 圧縮に対応したブラウザ(すべてのモダンブラウザ)のためにコンテンツを圧縮します。

このミドルウェアは、レスポンスボディを読み書きする必要がある他のミドルウェアよりも前に配置するべきです。圧縮がその後に行われるようにするためです。

次のいずれかが当てはまる場合、コンテンツは圧縮されません:

  • コンテンツ・ボディの長さが200バイト未満。
  • レスポンスがすでに Content-Encoding ヘッダを設定している。
  • リクエスト(ブラウザ)が Accept-Encoding ヘッダに gzip を含んでいない。

もしレスポンスに ETag ヘッダーがあれば、ETag は、RFC 9110#section-8.8.1 に準拠するために弱い形式になります。

gzip_page() デコレータを使用して、個別のビューに GZip 圧縮を適用できます。

Conditional GET middleware

class ConditionalGetMiddleware

条件付きGET操作を扱います。レスポンスに ETag ヘッダーがない場合、必要に応じてミドルウェアが追加します。レスポンスに ETag または Last-Modified ヘッダーがあり、リクエストに If-None-Match または If-Modified-Since がある場合、レスポンスは HttpResponseNotModified に置き換えられます。

Locale ミドルウェア

class LocaleMiddleware

リクエストからのデータに基づいた言語セクションを有効化します。この機能は、それぞれのユーザに対してコンテンツをカスタマイズします。 国際化のドキュメント を参照してください。

LocaleMiddleware.response_redirect_class

デフォルトは HttpResponseRedirect です。LocaleMiddleware をサブクラス化して属性をオーバーライドし、ミドルウェアによって発行されたリダイレクトをカスタマイズします。

Message ミドルウェア

class MessageMiddleware

クッキーおよびセッションをベースとしたメッセージサポートを有効化します。メッセージのドキュメント を参照してください。

Security middleware

警告

デプロイメントの状況によっては、通常、フロントエンドのウェブサーバーが SecurityMiddleware が提供する機能を実行するのが良いです。これにより、Djangoで処理されないリクエスト(静的メディアやユーザーがアップロードしたファイルなど)も、Djangoアプリケーションへのリクエストと同じ保護を受けることができます。

class SecurityMiddleware

django.middleware.security.SecurityMiddleware は、リクエスト/レスポンスサイクルに複数のセキュリティ強化機能を提供します。それぞれの機能は、設定を使って個別に有効または無効にできます。

HTTP Strict Transport Security

HTTPSでのみアクセスする必要のあるサイトでは、 "Strict-Transport-Security" header を設定することで、一定期間、モダンブラウザに対して、セキュアでない接続を通じてドメイン名に接続しないように指示できます。これにより、SSLストリッピング型の中間者攻撃 (MITM) に対するリスクを軽減できます。

SecurityMiddleware は、SECURE_HSTS_SECONDS 設定をゼロ以外の整数値に設定すると、すべての HTTPS レスポンスに対してこのヘッダーを自動的に設定します。

HSTSを有効にする際には、最初に小さい値をテスト用に使用することをお勧めします。たとえば、1時間の場合は SECURE_HSTS_SECONDS = 3600 です。ウェブブラウザがあなたのサイトからHSTSヘッダーを検知するたびに、指定された期間、非セキュアな通信(HTTPを使用)をあなたのドメインと行うことを拒否します。サイト上の全てのアセットが安全に提供されていること(つまり、HSTSが何も壊していないこと)を確認できたら、頻繁でない訪問者も保護されるようにこの値を増やすことをお勧めします(一般的には31536000秒、すなわち1年が普通です)。

また、SECURE_HSTS_INCLUDE_SUBDOMAINS 設定を True に設定すると、SecurityMiddlewareStrict-Transport-Security ヘッダーに includeSubDomains ディレクティブを追加します。これは推奨です (すべてのサブドメインが HTTPS を使用してのみ提供されている場合)。それ以外の場合、サイトはまだサブドメインへの安全でない接続を介して脆弱になる可能性があります。

browser preload list にサイトを登録する場合は、 SECURE_HSTS_PRELOAD 設定を True に設定してください。これにより、 Strict-Transport-Security ヘッダーに preload ディレクティブが追加されます。

警告

HSTSポリシーは、ヘッダーを設定したレスポンスのURLだけでなく、ドメイン全体に適用されます。したがって、ドメイン全体がHTTPS経由のみで提供される場合にのみ使用すべきです。

HSTSヘッダーを適切に尊重するブラウザは、期限切れ、自己署名、またはその他の無効なSSL証明書を持つサイトに警告をバイパスして接続することをユーザーに許可しません。HSTSを使用する場合は、証明書が適切な状態にあることを確認し、維持してください!

注釈

ロードバランサーやリバースプロキシサーバーの後ろに配置されている場合、そして Strict-Transport-Security ヘッダーがレスポンスに追加されていない場合は、Djangoが安全な接続上にあることを認識していない可能性があります。その場合、SECURE_PROXY_SSL_HEADER 設定を行う必要があるかもしれません。

リファラ・ポリシー

ブラウザは、ユーザーがどのようにそのサイトに到達したかについての情報をサイトに送信する手段として、 the Referer header を使用します。ユーザーがリンクをクリックすると、ブラウザはリファラとしてリンク元ページの完全な URL を送信します。これにより、誰があなたのサイトにリンクしているかを特定するなどの目的には役立ちますが、同時に、ユーザーが別のサイトを訪れていたことを1つのサイトに通知することでプライバシー上の懸念が引き起こされる可能性もあります。

一部のブラウザには、ユーザーがリンクをクリックした際に HTTP Referer ヘッダを送信すべきかについてのヒントを受け入れる機能があります。このヒントは the Referrer-Policy header を介して提供されます。このヘッダは、ブラウザに対して3つの動作のいずれかを提案できます:

  • 完全なURL: Referer ヘッダーには、完全なURLを送信します。たとえば、ユーザーが https://example.com/page.html を訪問している場合、Referer ヘッダーには "https://example.com/page.html" が含まれます。
  • Origin のみ: referrerには "origin" のみを送信します。origin はスキーム、ホスト、(オプションで) ポート番号から構成されます。例えば、ユーザーが https://example.com/page.html を訪問している場合、origin は https://example.com/ となります。
  • リファラなし: Referer ヘッダーを一切送信しません。

このヘッダーがブラウザーに注意を促す条件は2種類あります:

  • 同一オリジンとクロスオリジン: https://example.com/1.html から https://example.com/2.html へのリンクは同一オリジンです。 https://example.com/page.html から https://not.example.com/page.html へのリンクはクロスオリジンです。
  • プロトコルのダウングレード: リンクを含むページがHTTPS経由で提供されている場合、リンク先のページがHTTPS経由で提供されていない場合にダウングレードが発生します。

警告

サイトが HTTPS 経由で提供される場合、Django の CSRF 保護システムReferer ヘッダーが存在することを要求するので、Referer ヘッダーを完全に無効にすることは CSRF 保護の妨げになります。 Referer ヘッダーを無効にすることの多くの利点を享受しつつ、CSRF 保護も維持するには、同一オリジンのリファラーのみを有効にすることを検討してください。

SecurityMiddleware は、SECURE_REFERRER_POLICY 設定に基づいて Referrer-Policy ヘッダを設定できます(スペルに注意: ブラウザはユーザーがリンクをクリックすると Referer ヘッダを送信しますが、ブラウザにこれを行うかどうかを指示するヘッダは Referrer-Policy と綴られます)。この設定の有効な値は次の通りです:

no-referrer
このサイト上でクリックされたリンクに対して、ブラウザにリファラを送信しないよう指示します。
no-referrer-when-downgrade
ブラウザに、プロトコルのダウングレードが発生しない時にのみ、完全なURLをリファラとして送信するよう指示します。
origin
ブラウザに、リファラとして完全な URL ではなく、オリジンのみを送信するよう指示します。
origin-when-cross-origin
ブラウザに、同一オリジンのリンクでは完全なURLをリファラとして送信するように指示し、クロスオリジンのリンクではオリジンのみを送信するようにします。
same-origin
ブラウザに対し、同一オリジンのリンクについては完全なURLを送信するよう指示します。クロスオリジンのリンクに対しては、リファラは送信されません。
strict-origin
ブラウザに、プロトコルのダウングレードが発生した場合に、完全なURLではなくオリジンのみを送信するよう指示し、リファラを送信しないようにします。
strict-origin-when-cross-origin
同一オリジンでプロトコルのダウングレードが発生しない場合、ブラウザには完全なURLを送信するよう指示します。クロスオリジンでプロトコルのダウングレードが発生しない場合、ブラウザにはオリジンのみを送信するよう指示します。プロトコルのダウングレードが発生する場合はリファラを送信しません。
unsafe-url
ブラウザに常に完全なURLをリファラとして送信するよう指示します。

ポリシーの値が unknown の場合

ユーザーエージェントによってポリシー値が unknown とされた場合、フォールバックを提供するために複数のポリシー値を指定できます。解釈可能な最後に指定された値が優先されます。これをサポートするために、イテラブルもしくはカンマで区切られた文字列が SECURE_REFERRER_POLICY の設定として使用できます。

同一生成元ポリシー (Cross-Origin Opener Policy)

一部のブラウザは、 Cross-Origin Opener Policy (COOP) ヘッダーの値に基づいて、トップレベルウィンドウを他のドキュメントから分離する能力を持っています。この分離によって、特定のドキュメントがクロスオリジンのポップアップウィンドウを開いた場合、そのポップアップの window.opener プロパティは null になります。COOP を使用したウィンドウの分離は、特に Spectre のような、共有されたブラウジングコンテキストに読み込まれたデータの外部への持ち出しを可能にしたクロスオリジン攻撃に対する深層防御保護です。

SecurityMiddleware は、 SECURE_CROSS_ORIGIN_OPENER_POLICY 設定に基づいて、 Cross-Origin-Opener-Policy ヘッダーを設定できます。この設定の有効な値は以下の通りです:

same-origin
同じオリジンのドキュメントに閲覧コンテキストを排他的に限定します。異なるオリジンのドキュメントは同じ閲覧コンテキストで読み込まれません。これがデフォルトで最も安全なオプションです。
same-origin-allow-popups
ブラウジングコンテキストを同一オリジンのドキュメントに限定します。または、COOP を設定しないドキュメントや、COOP を unsafe-none に設定して隔離からオプトアウトするドキュメントに限定します。
unsafe-none
ドキュメントを、オープナー自体が same-origin または same-origin-allow-popups のCOOPを持っている場合を除いて、そのオープナーのブラウジングコンテキストグループに追加できるようにします。

X-Content-Type-Options: nosniff

一部のブラウザーは、取得したアセットのコンテンツタイプを推測し、 Content-Type ヘッダーを上書きしようとします。これは不適切に設定されたサーバーのサイトを表示する際に役立つことがありますが、セキュリティリスクをもたらすこともあります。

サイトがユーザーがアップロードしたファイルを提供する場合、悪意のあるユーザーが特別に作成したファイルをアップロードする可能性があります。そのファイルが無害なものだと思っていたのに、ブラウザでHTMLまたはJavaScriptとして解釈されてしまう恐れがあります。

ブラウザがコンテンツタイプを推測し、常に Content-Type ヘッダーで提供されたタイプを使用するように強制するために、X-Content-Type-Options: nosniff ヘッダーを渡すことができます。 SECURE_CONTENT_TYPE_NOSNIFF 設定が True であれば、 SecurityMiddleware は全てのレスポンスに対してこれを行います。

ほとんどのデプロイ状況では、ユーザーがアップロードしたファイルの配信に Django が関与しないため、この設定は助けになりません。たとえば、MEDIA_URL がフロントエンドのウェブサーバー (nginx や Apache など) から直接配信される場合は、このヘッダーを設定することをおすすめします。一方で、たとえばもし認可が必要なファイルをダウンロードするために Django を使用していて、ウェブサーバーを使ってヘッダーを設定することができない場合、この設定が役に立つでしょう。

SSL リダイレクト

サイトが HTTP と HTTPS 接続の両方をサポートしている場合、多くのユーザーはデフォルトでセキュアでない接続を行ってしまいます。最善のセキュリティのためには、すべての HTTP 接続を HTTPS 接続にリダイレクトするべきです。

SECURE_SSL_REDIRECT 設定を True に設定すれば、 SecurityMiddleware が すべての HTTP 接続を HTTPS に parmanent (HTTP 301) にリダイレクトしてくれます。

注釈

パフォーマンス上の理由により、このようなリダイレクトは Django の外部、フロントエンドのロードバランサーや nginx などのリバースプロキシサーバーで実行した方が良いです。 SECURE_SSL_REDIRECT は、これらのオプションが使用できないデプロイ環境で使われることを想定しています。

SECURE_SSL_HOST 設定に値がある場合、全てのリダイレクトは元々要求されたホストではなく、その値で指定されたホストに送信されます。

サイトのいくつかのページをHTTP経由で利用可能にし、HTTPSにリダイレクトされないようにしたい場合は、 SECURE_REDIRECT_EXEMPT 設定にそれらのURLに一致する正規表現をリストアップできます。

注釈

ロードバランサーやリバースプロキシサーバーの後ろにデプロイしており、Django がリクエストが既に安全であるかどうかを正しく判断できない場合は、 SECURE_PROXY_SSL_HEADER 設定を行う必要があります。

Session middleware

class SessionMiddleware

セッションのサポートを有効にします。詳しくは セッションのドキュメント を読んでください。

Site ミドルウェア

class CurrentSiteMiddleware

受信側のすべての HttpRequest オブジェクトに、現在のサイトを表す site 属性を追加します。詳しくは sites のドキュメント を参照してください。

Authentication middleware

class AuthenticationMiddleware

HttpRequest オブジェクトに対して、現在ログインしているユーザーを表す user 属性を追加します。ウェブリクエストにおける認証 を参照してください。

class RemoteUserMiddleware

Web サーバーが提供する認証を利用するためのミドルウェアです。使用方法の詳細については REMOTE_USER で認証する を参照してください。

class PersistentRemoteUserMiddleware

ログインページでのみ有効にした場合の、Webサーバー提供の認証を利用するためのミドルウェアです。使い方の詳細については、 ログインページでのみ REMOTE_USER を使用する を参照してください。

CSRF プロテクション middleware

class CsrfViewMiddleware

POST フォームに隠しフォームフィールドを追加し、リクエストの値が正しいかチェックすることで、Cross Site Request Forgery に対するプロテクションを追加します。詳しくは Cross Site Request Forgery プロテクションのドキュメント を読んでください。

X-Frame-Options middleware

class XFrameOptionsMiddleware

シンプルな クリックジャッキングに対する X-Frame-Options ヘッダ経由のプロテクション です。

Middleware の順序

Django の多様なミドルウェアクラスの順序に関する注意点を挙げておきます。

  1. SecurityMiddleware

    SSL リダイレクトを有効にしているなら、他のたくさんの必要のないミドルウェアが実行されないように、リストの先頭付近に置くべきです。

  2. UpdateCacheMiddleware

    Vary ヘッダに変更を加えるミドルウェア (SessionMiddleware, GZipMiddleware, LocaleMiddleware) の前に置きます。

  3. GZipMiddleware

    response body を変更・使用する可能性のあるミドルウェアの前に置きます。

    Vary ヘッダを修正するため、 UpdateCacheMiddleware の後に置きます。

  4. SessionMiddleware

    CSRF_USE_SESSIONS を使用している場合、例えば PermissionDenied のようなエラービューをトリガーする例外を発生させる可能性のあるミドルウェアよりも前に配置してください。

    Vary ヘッダを修正するため、 UpdateCacheMiddleware の後に置きます。

  5. ConditionalGetMiddleware

    レスポンスを変更する可能性があるミドルウェアよりも前に設定してください (これは ETag ヘッダを設定します)。

    gzip されたコンテンツに対して ETag ヘッダを計算しないように、 GZipMiddleware の後に置きます。

  6. LocaleMiddleware

    SessionMiddleware (session データを使う) と UpdateCacheMiddleware (Vary ヘッダを修正する) の後のできるだけ高い位置に置きます。

  7. CommonMiddleware

    レスポンスを変更する可能性のあるミドルウェアの前に配置します (Content-Length ヘッダーを設定します)。 CommonMiddleware の前に配置され、レスポンスを変更するミドルウェアは、 Content-Length をリセットする必要があります。

    APPEND_SLASHPREPEND_WWWTrue に設定されているとリダイレクトされるので、先頭の近くに置きます。

    SessionMiddleware の後に、 CSRF_USE_SESSIONS を使用している場合。

  8. CsrfViewMiddleware

    CSRF 攻撃が可能なすべての view ミドルウェアの前に置きます。

    RemoteUserMiddleware の前、あるいはログインを実行し、CSRF トークンをローテートする可能性のある他の認証ミドルウェアの前、ミドルウェアチェインを呼び出す前に置きます。

    SessionMiddleware の後に、 CSRF_USE_SESSIONS を使用している場合。

  9. AuthenticationMiddleware

    session ストレージを使うので、 SessionMiddleware の後に置きます。

  10. MessageMiddleware

    session ベースの storage を使うので、 SessionMiddleware の後に置きます。

  11. FetchFromCacheMiddleware

    キャッシュのハッシュキーを生成するのに Vary ヘッダを使用するため、このヘッダを修正するすべてのミドルウェアのあとに置きます。

  12. FlatpageFallbackMiddleware

    最後に実行されるタイプのミドルウェアなので、できるだけ下に置く必要があります。

  13. RedirectFallbackMiddleware

    最後に実行されるタイプのミドルウェアなので、できるだけ下に置く必要があります。

Back to Top