Skip to main content

Djangoのセキュリティ対策のヒント

著者
Headshot of Hayley Denbraver

Hayley Denbraver

10 Django security tips header image

2020年3月25日

0 分で読めます

締め切りのある完璧主義者のためのWebフレームワーク(別名Django)をお使いの皆さんは幸運です!Djangoチームはセキュリティ対策に多くの工夫を凝らしています(ドキュメントにセキュリティ機能が掲載されており、セキュリティポリシーも参考になります)。Djangoプロジェクトを安全に保つためのベストなヒントをまとめました。

Djangoセキュリティ対策のヒントをまとめたチートシートをダウンロードしましょう。

Djangoのセキュリティに関する10のヒントをまとめたチートシート。安全なバージョン、認証、SQL、Cookie、アップロード、依存関係などを掲載。

バージョンを把握し、安全なバージョンを使う

現在、どのバージョンのDjangoを使っていますか?現在、Djangoには3つのメジャーバージョンが使われています(ただし、1.11の長期サポートは2020年4月に終了します)。使用しているDjangoのバージョンは、プロジェクトにさまざまな影響を及ぼします。たとえば、Django 1.11はPython 2を使用できる最後のバージョンです(Python 2は2020年初頭にサポートが終了しました)。

さらに、バージョンによって、アプリケーションに存在し、悪用される可能性のある既知の脆弱性も異なります。既知のDjangoの脆弱性については、脆弱性データベースをご覧いただくか、Snykでプロジェクトをスキャンしてください。脆弱なバージョンを使っている場合はお知らせします。

また、Djangoのバージョンを最新の状態に保つ計画を立てることも重要です。一般的には、長期サポート版を選び、現在のバージョンのサポート終了前に次のバージョンへ移行する計画を立てるとよいでしょう。これにより、メンテナーのサポートを受けながら、頻繁なバージョン変更を避けられます。

補足として、必ず使用中のDjangoバージョンに対応したドキュメントを参照してください。ドキュメントを読んでセキュリティポリシーが適用されていると思っていたのに、使用中のバージョンとドキュメントのバージョンが異なっていた、という事態は避けたいものです。

ユーザー認証の試行回数を制限する

Djangoには多くのセキュリティ機能が組み込まれていますが、認証システムだけではブルートフォース攻撃を防げません。攻撃者が大量のログインを試み、システムへの侵入に成功する可能性があります。

この種の攻撃がプロジェクトで懸念される場合は、Django Defenderのようなプロジェクトを利用し、ログイン試行回数が上限を超えたユーザーをロックアウトしましょう。

ソースコードを保護する

ソースコードの保護は当たり前に思えるかもしれませんが、さまざまな側面があるため、詳しく見ておく価値があります。保護する方法の一つは、Webサーバーのルートディレクトリにソースコードを置かないことです。そこに置くと、意図しない形でコードの一部が配信されたり、実行されたりする可能性があります。

言うまでもありませんが、プロジェクトに機密情報が含まれる場合は、GitHub、Bitbucket、GitLabでプライベートリポジトリを使いましょう。また、プライベートリポジトリを使うつもりかどうかにかかわらず、シークレットをバージョン管理システムに絶対にコミットしないでください。プライベートリポジトリが常に非公開のままとは限らず、アクセス権を持つ人を必ずしも信頼できるとは限りません。

生のクエリやカスタムSQLは慎重に使う

生のSQLクエリやカスタムSQLを書きたくなることもありますが、攻撃の糸口になる可能性があります。Djangoのオブジェクトリレーショナルマッピング(ORM)フレームワークは、データベースへの問い合わせを簡単に行えるよう設計されています。QuerySetはクエリパラメーター化を使って構築され、クエリのパラメーターはSQLコードから分離されています。ORMを常に使えば、SQLインジェクション(データベース上で任意のSQLを実行する攻撃)を試みるユーザーにとって、攻撃ははるかに困難になります。

Djangoでは生のクエリも使えますが、推奨されていません。使う場合は、パラメーターを適切にエスケープするよう特に注意してください。Django ORMでは要件を満たせない場合、Djangoで別のORMを使うこともできます。SQLAlchemyはDjangoで利用できるORMの一例です。プロジェクトにより適したORMがあるなら、大量の生SQLを書くよりも、そちらを利用するのがおすすめです。

HTTPSを使う

どのフレームワークを選ぶ場合でも、HTTPS経由でデプロイするのが望ましいです。これにより、クライアントとサーバー間で送信される情報を攻撃者に傍受されるのを防げます。HTTPSを正しく機能させるには、設定が適切であることを確認してください。

HTTPSを使ううえで重要な設定は次のとおりです。それぞれの意味を理解し、適切に有効化してください。ドキュメントには各設定や安全なデフォルト値、状況に応じて変更が必要となる理由が分かりやすく説明されています。

ヘッダーに注意する

まず、Refererリクエストヘッダーについて考えてみましょう。このヘッダーには、現在のページに移動する前に閲覧していたWebページのアドレスが含まれます。この情報は、分析などに役立ちます。一方で、Web上の行動を追跡されるのを好まない人も多く、問題になることがあります。プライバシー上の懸念から、この機能を無効にすることも可能です。Refererリクエストヘッダーを引き継ぐかどうかは、Referrer-Policyヘッダーで指定できます。条件によって、一部の情報だけが引き継がれる場合も、すべての情報が含まれる場合もあり、Refererリクエストヘッダーの情報が一切転送されない場合もあります。

サイトがHTTPS経由で配信されている場合、Djangoはクロスサイトリクエストフォージェリ(CSRF)攻撃の防止にRefererリクエストヘッダーを利用します。Referrer-Policyヘッダーを厳しく設定しすぎると、DjangoのCSRF保護が機能しなくなります。厳格なReferrer-Policyヘッダーによるプライバシー上のメリットと、CSRF保護のメリットを比較して判断する必要があります。Referrer-Policyヘッダーで同一オリジンのリファラーのみを許可すれば、両者のバランスを取ることができます。

Cookieには安全性の高いものと低いものがあり、デフォルトではHTTP経由で送信されます。すでに説明したようにHTTPSを使う必要があるため、CookieもHTTPS経由でのみ送信されるようにしましょう。Cookieの漏えいを防ぐには、SESSION_COOKIE_SECUREとCSRF_COOKIE_SECUREをTrueに設定してください。これにより、ブラウザーはHTTPS接続でのみCookieを送信するようになります。これらのパラメーターをTrueにするといくつか影響がありますが、HTTPトラフィックをHTTPSにリダイレクトすることで対処できます。

ユーザーによるアップロードを慎重に処理する

Webアプリケーションでユーザーのファイルアップロードを許可すると、攻撃対象となる経路が生まれるため、アップロード処理は慎重に行う必要があります。まず、アップロードされたファイルが想定どおりのもの(たとえばPHPスクリプトではなく画像ファイル)であることを、すべて検証してください。ユーザーがコードを実行できる状態は避けなければなりません。

アップロードされたファイルを検証したり、より慎重に扱ったりする方法はいくつかあります。以下に例を挙げます。

  • 許可するファイル形式のホワイトリストを作成する

  • サービス拒否攻撃を防ぐため、アップロードできるファイルサイズを制限する

  • 静的ファイルをコードとして実行するハンドラーを無効にする(例:Apacheのmod_phpを無効にする)

  • クロスサイトスクリプティング対策を活用しましょう。ユーザーコンテンツを異なるトップレベルドメインから配信すれば、クロスサイトスクリプティング対策が働き、保護につながります。管理しているドメインを使うこともできますが、クラウドサービスやコンテンツ配信ネットワークからファイルを配信するほうが簡単でしょう。

すべての依存関係を把握する

既知のセキュリティリスクがほとんどない、あるいはまったくないDjangoのバージョンを選んだなら、もうセキュリティ上の問題はないと思うかもしれません。しかし、Djangoが取り込むオープンソースライブラリを把握し、それらに脆弱性がないか確認することが重要です。

Django(またはその他のオープンソースライブラリ)を使うと、通常、選んだライブラリが利用するライブラリもすべて一緒に取り込むことになります。オープンソースは、さらに別のオープンソースの上に成り立っています。

間接依存関係も直接依存関係と同様にリスクをもたらしますが、そのリスクは見落とされやすいものです。Snykのようなツールを使えば、依存関係ツリー全体を把握できます。さらに、SnykではPython向けの修正プルリクエストを利用できるため、間接依存関係を含む問題もこれまで以上に簡単に修正できます。

完璧を求めすぎて、できることを後回しにしない

セキュリティ対策は、取り組むたびに前進します。Djangoは締め切りのある完璧主義者のためのフレームワークですが、セキュリティ上のメリットを得るためにコードが完璧である必要はありません。ここまで紹介した考え方をできる範囲で実践すれば、コードの安全性が大きく向上し、より健全で回復力の高いプロジェクトにつながります。Pythonistaの皆さん、楽しいコーディングを!

Capture the Flagを始めよう

オンデマンドのバーチャル入門ワークショップを見て、Capture the Flagの課題の解き方を学びましょう。

続きを読む

feature insights context
Blog

自律型攻撃はすでに始まっている。防御もそのスピードに追いつかなければならない。

自律型攻撃者によって、防御に使える時間は短くなっています。継続的な検出、修復、検証、予防で、セキュリティチームが攻撃に歩調を合わせる方法をご紹介します。

illustration hero ai
Blog

AIハリケーンが到来

AIはソフトウェア開発とサイバー攻撃の双方を加速させています。リーダーは、エージェントとコードを開発の初期段階から保護し、実行時に制御を徹底するとともに、防御策を独立して検証しなければなりません。

feature insights context
Blog

予防は、本質的に解決済みの問題なのでしょうか?

エージェントが生成するコードの予防策はアーキテクチャ上解決されていますが、開発を遅らせることなくセキュリティを守る制御を選ぶことが、依然として課題です。