DjangoのALLOWED_HOSTSの役割と使い方
- 作成日: 2021-01-11
- 更新日: 2023-12-24
- カテゴリ: Django
DjangoのALLOWED_HOSTSの役割と使い方
PythonのWebフレームワークであるDjango(ジャンゴ)には数々のセキュリティ対策が実装されています。
settings.py
内に設定するALLOWED_HOSTSというリストもそのセキュリティ対策の一部です。
この記事ではALLOWED_HOSTS
の役割と使い方を解説します。
具体的には↓を見ていきます。
- ALLOWED_HOSTSの役割
- ALLOWED_HOSTSの仕組み
- ALLOWED_HOSTSの使い方
- ソースコードの解析
ALLOWED_HOSTSの役割
Djangoのプロジェクトのsettings.py
に書かれれるALLOWED_HOSTS
は、HTTPのホスト・ヘッダー攻撃を防ぐためのリストです。
このリストにコンテンツを配信するサーバー自身のホスト名を書くことで、そのホスト名がホワイトリストの役割をして外部からの攻撃を防ぎます。
ホスト・ヘッダー攻撃とはたとえば↓のような攻撃です。
- クロスサイトリクエストフォージェリ
- キャッシュポイズニング攻撃
- メール内のポイゾニングリンク
ALLOWED_HOSTSの仕組み
ALLOWED_HOSTS
のデフォルト値は空のリスト([]
)です。
ALLOWED_HOSTS
の値はdjango.http.HttpRequest.get_host()
メソッド内で参照されます。
django.http.HttpRequest.get_host()
メソッドは内部でALLOWED_HOSTS
をホワイトリストとして参照し、現在のリクエストのホストとのバリデーションを行います。
バリデーションに失敗した場合はSuspiciousOperation
を発生させます。
ALLOWED_HOSTS
のリスト内の値は文字列です。
この文字列はFQDN(完全修飾名: 例 www.example.com
)で記述することが出来ます。
この場合はバリデーション時にリクエストのホストヘッダーと正確にマッチを行います。
大文字小文字を区別せず、ポートは含めません。
ピリオドで始まる値をサブドメインのワイルドカードとして使えます。
たとえば.example.com
などです。この値はexample.com
とwww.example.com
、またexample.com
のサブドメインにそれぞれマッチします。
この場合、ホストヘッダの検証はミドルウェアなどを使って自分で行う必要があります。
DEBUG
がTrue
でかつALLOWED_HOSTS
が空のリストの場合はdjango.http.HttpRequest.get_host()
は.localhost
, 127.0.0.1
, [::1]]
を使ったバリデーションを行います。
また値にはワイルドカード(*
)を使うことも出来ます。
ALLOWED_HOSTSの使い方
開発環境の場合のドメインはlocalhost
が多いと思います。
ですので開発環境下に限定したい場合はALLOWED_HOSTS
の記述は↓のようになります。
ALLOWED_HOSTS = [
'localhost',
'www.localhost',
]
配信中のサービスがexample.com
で開発環境も考慮する場合は↓のようになります。
ALLOWED_HOSTS = [
'example.com',
'www.example.com',
'localhost',
'www.localhost',
]
また、ワイルドカードを使ってすべてのホストを許可することも出来ます。
ALLOWED_HOSTS = ['*']
ソースコードの解析
django.http.HttpRequest.get_host()
のコードを見てみます。
コードを見るとsettings.py
のALLOWED_HOSTS
が参照されているのがわかります。
また、DEBUG
がTrue
でかつALLOWED_HOSTS
が空の場合はallowed_hosts = ['.localhost', '127.0.0.1', '[::1]']
でホストのリストを初期化しています。
その後にリクエストのホストをポートとドメインに分割し、ドメイン部分のみにallowed_hosts
を使ってバリデートしています。
バリデートに成功した場合はリクエストのホスト名を返し、失敗した場合はDisallowedHost
オブジェクトを返しています。
エラー内容は↓のいずれかになります。
Invalid HTTP_HOST header: ホスト名. You may need to add ドメイン名 to ALLOWED_HOSTS.
Invalid HTTP_HOST header: ホスト名. The domain name provided is not valid according to RFC 1034/1035.
おわりに
今回はDjangoのALLOWED_HOSTS
を見て見ました。
入門初期から認識が必要になるリストですが、その実体についてはけっこうあいまいに覚えてる人も多いのではないでしょうか。
🦝 < ピッピ! 君はだめ。君はOK
🐭 < ホストの番人ALLOWED_HOSTS