このドキュメントの Django のバージョンにはセキュリティ上の脆弱性があるため、すでにサポートが終了されています。新しいバージョンにアップグレードしてください!最新の Django のバージョンのドキュメントはこちら

Django v1.0 documentation

クロスサイトリクエストフォージェリ (CSRF) 対策

revision-up-to:8961 (1.0)

CsrfMiddleware クラスは、簡単に使える クロスサイトリクエストフォージェリ 対策を提供しています。このタイプの攻撃は、悪意あるウェブサイトが、あなたの ウェブサイトに対して、ログイン済みユーザの権限で何らかの操作を行うように作 られたリンクやフォームボタンを自分のサイトに設置しておき、ログイン済みのユー ザがユーザが自分のブラウザを使ってボタンやリンクをクリックするように仕向け ることで起こります。

CSRF 攻撃に対する第一の防御は、 GET リクエストから副作用を取り除くというも のです。 POST リクエストに対する防御は、このミドルウェアをインストール済み ミドルウェアリストに追加して実現できます。

使い方

'django.contrib.csrf.middleware.CsrfMiddleware' ミドルウェアを MIDDLEWARE_CLASSES に追加してください。このミドルウェアは SessionMiddleware よりも後にレスポンスを処理せねばならないので、リスト中の SessionMiddleware よりも前に配置します。また、圧縮のような操作が入る前のレ スポンスを処理せねばならないので、 GZipMiddleware よりも後に配置します。

仕組み

CsrfMiddleware は以下のような処理を行います:

  1. CsrfMiddleware は、サーバから出てゆくレスポンス内の ‘POST’ フォーム全て に対して ‘csrfmiddlewaretoken’ という名前の隠しフィールドを追加します。 このフィールドの値はセッション ID とシークレット文字列の和をハッシュした ものになります。セッション ID が設定されていない場合、レスポンスに対する 変更は行いません。このため、セッションをともなわないリクエストに対しては 非常にわずかなパフォーマンスペナルティしかもたらしません。
  2. セッションクッキーのセットされた全ての POST リクエストに対し、 ‘csrfmiddlewaretoken’ がセットされていて、かつ正しい値になっているか調べ ます。正しい値でなければ、 403 エラーを返します。

これらの処理により、あなたのウェブサイト由来のフォームだけが POST を送り返 せるようになります。

このミドルウェアは、 HTTP POST リクエスト (と POST フォーム) だけを対象にし ています。 GET リクエストには危険な副作用を持たないはず (RFC 2616: HTTP 1.1 の 9.1.1 節、「安全なメソッド」 を参照) なので、 GET リクエストを使った CSRF 攻撃は威力を持たないのです。

セッションクッキーを伴わない POST リクエストは保護されませんが、セッション クッキーを伴わないようなフォームに対しては、攻撃側のウェブサイトはリクエス トをどのようにでも作れてしまうので、そもそも保護する意味はありません。

CsrfMiddleware はレスポンスを変更する前に Content-Type をチェックし、 ‘text/html’ または ‘application/xml+xhtml’ のページだけを変更します。

制限

CsrfMiddleware を動作させるには、 Django のセッションフレームワークが必要で す。手動でクッキーを設定するカスタムの認証システムなどを使っている場合には うまく動作しません。

アプリケーションで HTML ページやフォームを普通とは違うやり方で生成している 場合 (JavaScript の document.write 文などで HTML フラグメントを送信するよう な場合)、フォームの隠しフィールドを追加するフィルタを回避してしまうかもしれ ません。そのような場合、フォームの提出は常に失敗してしまいます。ただし、 CSRF 対策トークンを取得し、提出されるフォームに必ずトークンが入るようにすれ ば、このミドルウェアを使う余地はあるでしょう。