2018/08/20)問題:まちがった自動ログイン処理の解答です。このブログエントリは最近作られたアプリケーションでは「問題」にしたような実装は行われていないはず、と期待していたのですがあっさり期待を破られたのでブログに書きました。このブログの方が詳しく書いていますけが「Webアプリセキュリティ対策入門」にも正しい自動ログイン処理を書いています。参考:自動ログイン以外に2要素認証も重要です。「今すぐできる、Webサイトへの2要素認証導入」こちらもどうぞ。HMACを利用した安全なAPIキーの送受信も参考にどうぞ。間違った自動ログイン処理の問題点まず間違った自動ログイン処理を実装しているコードの基本的な問題点を一つ一つ順番にリストアップします。クッキーにランダム文字列以外の値を設定しているクッキーにユーザ名が保存されているクッキーにパスワードが保存されているユーザ名・パスワードが保存されているクッキーは暗号化されていないBASE64エンコードされたキストである自動ログイン用にが保存されたクッキー(ユーザ名・パスワード)がアプリケーション全体で有効になっているクッキーにランダム文字列以外の値を設定しているセキュリティのベストプラクティスとしてはクッキーにユーザに関連するいかなる情報(暗号化された情報を含む)も保存すべきではありません。クッキーにユーザに関連した情報(ユーザID、パスワード、メール、氏名、etc)を保存しなければならないシステムである場合、設計を見直し、ユーザ情報をクッキーに保存しなくても良い設計にしなければなりません。クッキーに保存しても良い値は、表示設定などのユーザ情報と関係の無い情報、セッションIDなどの予測不可能なランダムな値のみです。最小化の原則」があります。クッキーに保存する必要が全く無いユーザ名とパスワードをクッキーに保存することはこれらの原則にも適合していません。クッキーにユーザ名、パスワードが保存されている問題のコードではユーザ名、パスワードを含んだクッキーがBASE64でエンコードされていますがBASE64は暗号化とは言えません。テキストで送信しているのと変わりありません。仮に暗号化していてもクッキーにユーザ名とパスワードを保存するのは非常に危険です。そもそも既に記述したようにクッキーに重要な情報を保存する設計となっている場合、設計自体に問題があると言えます。問題のコードではユーザ名、パスワードを含んだクッキーがアプリケーション全体で有効になっています。サイト全体でない分ましですが非常に重要なクッキーを保存しているので不十分極まりない、と言われても仕方ないです。自動ログインの実装にユーザ名とパスワード(クレデンシャル)をクッキーに保存する方法はセキュリティ上大きな問題があります。コードの作者は「HTTPのBASIC認証でも同じような仕組みになっている」と考えられているかも知れません。そもそもBASIC認証自体が安全ではなく通常利用は避けるべきです。クレデンシャルをクッキーに保存するのはBASIC認証にはないリスクを増加させます。クッキーはPCにファイルとして保存されるファイルとして保存されるため有効期限が(通常は)非常に長い(問題のアプリは30日)クロスサイトスクリプティング(XSS、JavaScript挿入)に脆弱な場合簡単に盗まれる自動ログインの性質上、自動ログインに利用するクッキーは必ずファイルに保存されるクッキーとして送信しなければなりません。BASIC認証の場合、クレデンシャルはファイルに保存されません。セッションクッキーと同様にブラウザを終了すると消えてしまいます。自動ログイン通常は非常に長い期間(1週間から1ヶ月)保存されます。長い期間保存されるクッキーは悪用される可能性が高くなります。問題のアプリのクッキーには変化が無くBASE64エンコードされた内容を知らなくても再生攻撃で簡単に攻撃されます。アプリケーション全体で常に送信されるクッキーであることもリスクを増加させています。クッキーとして保存された情報はXSSに対してアプリケーションが脆弱であると簡単に盗むことができます。ブログアプリケーションはXSSに脆弱になりがちなので非常に危険といえます。BASIC認証のクレデンシャルを盗むには盗聴など、XSSより高いハードルを乗り越える必要があります。(ただし、最近は盗聴のリスクが増加しているので盗聴は行われている前提でアプリケーションを作るべきです。)また、共有PCを使っている場合はクッキーファイルを参照して簡単にドメイン名、ユーザ名、パスワード、アクセスに必要な情報全てが簡単に盗み出せます。自動ログインの実装方法に次の3つの方法がよく見かけられます。最後の最も好ましい実装は以下の様な手順で自動認証を行います。インデントが無くなって表示されていますが切れて見えないよりましなのでこのままにします。