Djangoの認証を独自に実装してはいけない
DjangoのAdminユーザーとフロントユーザーを完全に別テーブルで分けたい、というニーズがあります。しかし、Django標準の認証機構で扱えるのが1つのユーザーモデルのみのため、フロントユーザーのテーブルを独自に用意し、そのログイン認証を独自実装するケースがあります。 しかし、認証を安全に実装するのは非常に難しく、セキュリティーリスクが高くなるため、安易に独自実装するべきではありません。 独自実装一問一答
Q. ID/PWを照合するだけなので、ちょっとコードを書けばできるんじゃない?
A. 認証機構を自分で書いた場合、セキュリティーホールの原因になる可能性が高くて怖いです。
Q. どんなセキュリティーホールが考えられるんですか?
A. 分かりません。どんなケースがありえるのか、考えるのが大変です。
Q. パスワードをハッシュ化してDBに保存すれば十分じゃないの?
A. 何を持って十分と言うのか、その境界線を決めるのも大変です。
Q. じゃあDjangoの認証と同じハッシュ方式にすればいいんじゃない?
A. ハッシュ方式だけ同じにしても十分ではなさそうです。ソルトの選択や、将来そのハッシュ方式の脆弱性が判明した場合にハッシュ方式を変更するかもしれないので、その対応も必要になりそうです。
Q. そんなには何でもかんでも欲しいわけじゃ無い。安全な必要最低限の実装にしたい
A. 誰かが決める必要がありますが、ガイドラインがIPAにあります。IPAが注意喚起しているセキュリティー対策を施す場合、Djangoの認証機構を使えるようにするよりも時間がかかります。
Q. とりあえず最低限で実装して、セキュリティーホールがあると分かってから対策を考えればいいんじゃないの?
A. IPAが注意喚起しているセキュリティー対策を怠った場合、裁判で損害賠償となった判例があります
Q. IPAのセキュリティー対策を簡単に適用する方法は?
A. 既に実装されているDjangoの認証機構を使うのがオススメです。セキュリティー上の問題が仮に見つかっても、すぐに修正されるので安心ですよ。
Djangoの認証機構が提供する機能
画面
ログインview (独自実装で、ID不正とパスワード不正とでエラーメッセージを変えるとID存在確認が可能になるためNG)
ログアウトview
Django Adminのユーザー登録フォーム
パスワード変更フォーム
パスワードリセットフォーム(独自実装で、emailが見つからないエラーを表示すると、emailアドレス存在確認が可能となるためNG)
コード
セッション
認証のキャッシュ、セッションの作成、cookieの設定
テスト
Webクライアントによる認証済みユーザーの提供
Djangoの認証機構を利用しないことで考えられる不利益
Django認証機構と同じ機能を提供したい場合、独自に実装が必要(工数=機能数による)
Django認証機構を前提とした3rd-Partyライブラリが利用できない(ライブラリの機能数による)
例えば: Django REST Framework (DRF), 登録時のメール確認
工数を抑えるための部分的な実装によって安全性がどう変わるかを確認するコストがかかる
セキュリティー上のリスクが見つかった場合、改修コストが高い
参考文献