Django のセキュリティ

このドキュメントは Django のセキュリティ機能の概要です。 Django を使ったサイト をセキュアにするためのアドバイスも含んでいます。

クロスサイトスクリプティング (XSS) 対策

XSS 攻撃は、ユーザが他のユーザのブラウザ内にクライアントサイドスクリプトを挿入 することを可能にするものです。普通これは、悪意のあるスクリプトをデータベースに 保存し、他のユーザに検索、表示させたり、攻撃者の JavaScirpt が実行されるリンク をユーザにクリックさせることによって行われます。しかしながら XSS 攻撃は、デー タがページに含められる前に十分にサニタイズしておかなければ、他の信頼できない データソース、例えばクッキーや Web サービスのようなものから、起こる可能性があ ります。

Django テンプレートを使うとほとんどの XSS 攻撃を防ぐことができます。しかしなが ら Django が提供している防御と制限を理解しておくことが大切です。

Django テンプレートは HTML にとって特に危険な 特定の文字列をエスケープ します。これによって、ユーザはほとんどの悪意ある入 力から保護されますが、完全なフールプルーフではありません。例えば、以下は保護さ れません。

<style class={{ var }}>...</style>

もし var'class1 onmouseover=javascript:func()' がセットされていた ら、作成者不明の JavaScript が実行されることになります。これはブラウザが不完全 な HTML をどのようにレンダするかにも依存します。

また、カスタムテンプレートタグとともに is_safe を使ったり、 :safe テンプレートタグや mark_safe を使ったり、オー トエススケープをオフにしている時には、特に注意することが大切です。

加えて、テンプレートシステムを使って HTML ではない何かを出力しようとしているな ら、エスケープが必要な文字と単語は全く違ったものになります。

また、データベースに HTML を保存する時、特にそのHTMLが取り出されて表示される時 はとても注意深くならなければいけません。

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

CSRF 攻撃は悪意のあるユーザが、別のユーザの知識も同意もなく認証済情報を使った 行為を行えてしまうものです。

Django はほとんどの種類の CSRF 攻撃に対する組込の対策を備えていて、開発者はそ れを適切に 有効化して使う ことができます。しかしながら、他 の制限緩和テクニックと同様、対策に制限をかけることもできます。例えば CSRF モ ジュールを全体的に無効化したり、特定のビューで無効にすることが可能です。開発者 は、自分が何をしているのか分かっている時にだけしかそうすべきではありません。も しもサイトがコントロール不能なサブドメインを持っているなら、他の 制限 もあります。

CSRF 対策の動作 は POST リクエスト中のナンス (nonce) を検証することで成り立っています。これによって悪意のあるユーザが単純にウェブサ イトへのフォームでの POST を「再現」できないようになり、他のログインユーザが知 らずにサブミットしてしまうことを防げます。悪意あるユーザはユーザ個別の (クッ キーを使った) ナンスを知らなければなりません。

そうすることが絶対に必要なのでなければ、ビューを csrf_exempt デコレータで マークしないようにしてください。

SQL インジェクション対策

SQL インジェクションは悪意のあるユーザが任意の SQL コードをデータベース上で実 行できてしまう種類の攻撃です。この結果、レコードが削除されたり、データが漏洩す るといったことが起こりえます。

Django のクエリセットを使うと、出力される SQL は下層のデータベースドライバに よってうまくエスケープされます。しかし、 Django は開発者が 生のクエリ を書いたり カスタム SQL を実行することも許可しています。こ れらの技術はあくまで代替的な手段として使い、ユーザが変更できるパラメータは適切 にエスケープするよう注意しなければなりません。さらに extra() メソッドを使う場合は練習が必要です。

クリックジャッキング対策

クリックジャッキングは悪意のあるサイトがフレームの中に別のサイトを包み込む種類 の攻撃です。この攻撃の結果、疑いを持っていないユーザはターゲットサイトで意図し ない行為を実行させられてしまいます。

Django は クリックジャッキング対策X-Frame-Options middleware のフォームに含んでいます。 これはサポートしているブラウザがフレーム内にサイトを表示することを防ぐものです。 ビュー単位で対策を無効化したり、送信するヘッダの正確な値を設定することができま す。

サードパーティサイトによってフレーム内に表示される必要がない、またはサイトのご く一部でしかそれを許可しないサイトは、このミドルウェアを使うことを強くお勧めし ます。

SSL/HTTPS

全てのケースで現実的ではないかもしれませんが、サイトを HTTPS の背後にデプロイ することは、常にセキュリティ上良いことです。HTTPS を使わない場合、悪意のある ネットワークユーザが認証情報やクライアント・サーバ間でやりとりされる他の情報を 盗聴できてしまいます。そして場合によっては – 積極的な ネットワーク攻撃者 は – どちらかの方向に送られるデータを書き換えてしまいます。

HTTPS による対策が必要であり、サーバで HTTPS を有効にしたいなら、いくつかのス テップで、重要な情報が漏洩しないかをよく考えてください。

  • HTTP でのリクエストが HTTPS にリダイレクトされるように設定してください。

    小さな Django ミドルウェアで可能です。しかし Django アプリケーションがリバー スプロキシの後ろで動いているという一般的な場合の問題があります。 よくあることとして、リバースプロキシは X-Forwarded-SSL ヘッダ (または同 等の何か) を HTTPS での接続に対してセットするように設定されています。そこで このヘッダがなければリクエストが HTTPS ではないことを検知できます。しかしな がら、この方法は常に信頼できるわけではありません。クライアントや悪意のある ネットワーク攻撃者はこのヘッダをセットすることができます。

    そのため、リバースプロキシを使っている場合は、メインの Web サーバを HTTPS に リダイレクトするようにするか、アプリケーションへの HTTP リクエストを無条件に HTTPS にリダイレクトするように設定することをお勧めします。

  • 「セキュア」クッキーを使ってください。

    もしブラウザが最初に HTTP で接続してきたら、これはほとんどのブラウザのデフォ ルトですが、既に存在するクッキーが漏洩してしまいます。このため SESSION_COOKIE_SECURECSRF_COOKIE_SECURETrue に設定するべきです。これらのクッキーを HTTPS 接続でのみ送信するよう にというブラウザへの指示になります。 HTTP ではセッションが使えなくなり、 CSRF 対策によって HTTP での POST データは受け付けられなくなることに注意して ください。 (もし全ての HTTP トラフィック を HTTPS にリダイレクトしているので あれば問題ないでしょう)

Host ヘッダとバーチャルホスティング

Django はクライアントから送られた Host ヘッダを URL の構築に利用することが あります。クロスサイトスクリプティングを防ぐためにこの値をサニタイズしても、あ る環境ではクロスサイトリクエストフォージェリやキャッシュポイズニング攻撃に利用 されてしまいます。そのため Web サーバを以下のように設定することをお勧めします:

  • 渡された HTTP Host ヘッダが期待するホスト名か必ず検証する
  • Host ヘッダのないリクエストを許容しない
  • 全てのバーチャルホストへのリクエストを Django アプリケーションに転送する 設定にしない

加えて、 1.3.1 では、設定上必要であれば X-Forwarded-Host のサポートを明示 的に有効化するように Django は求めます。

さらなるセキュリティのトピック

Django は良いセキュリティ対策を提供していますが、アプリケーションを適切に配備 し、 Web サーバや OS や他のコンポーネントによるセキュリティ対策を利用すること も大切です。

  • Python コードが Web サーバの root 権限外で動作させてください。 Python コード がプレーンテキストで公開されていないか (または意図せず実行されていないか) を 確かめてください。
  • ユーザによるファイルアップロード の全てに気を 使ってください
  • Django は認証ユーザへのリクエストを抑制しません。認証システムへのブルート フォース攻撃を防ぐには Django のプラグインを使うか、これらのリクエストを制限 する Web サーバモジュールの利用を検討してください。
  • サイトがファイルアップロードを許可しているなら、サービス拒否 (DOS) 攻撃を防 ぐため、 Web サーバへのアップロードに制限をかけるよう強く忠告します。 Apache では LimitRequestBody ディレクティブで簡単に設定できます。
  • SECRET_KEY を秘密にしてください。
  • キャッシュシステムやデータベースへのアクセスをファイアウォールを使って制限す るのは良い考えです。