個人情報を保護する
今日から新しく個人情報保護法が適応されることになったので、ウェブアプリケーションを作成する際のちょっとしたワンポイントアドバイス。
データベースにはユーザのパスワードは保存しないこと。パスワードは画面上に表示することもないし、システム制作者が知る必要のあるデータではありません。ログイン処理を実装する時には、ユーザのパスワードを暗号化してデータを保存します。ログイン認証時にユーザから入力されたパスワードの正当性を確認する必要がある場合は、一度システムでそのパスワードを暗号化します。その暗号化されたデータが、データベース内に保存されているユーザの暗号化済みパスワードと一致するかを確認します。これで、万が一中身のデータが見られる事があっても、ユーザのパスワードは流用されません。世間一般の人は、一つのパスワードを多くのシステムや登録に使い回す事がおおいので、パスワードの流出を防ぐ事で、2次災害を防ぐ事ができます。
パスワードの暗号化には一方向性関数(つまりcrypt系)を使います。これは言葉の通り、双方向性が無く、一度暗号化したものを、元に戻すことはできません。システム運用者がユーザのパスワードを知らないということは、不便な場合も多いかも知れません。ユーザは必ずパスワードを忘れます。そのときは、運営者に問い合わせてきます。その時は、運営者はユーザのパスワードを確認することはできないので、再設定を行ってあげることになります。このコストはかなり高いと思われるかもしれませんが、セキュリティは高価なものなので、安全なサイトを運営するための代償として考えるしかないでしょう。
// コードサンプル
RegisterUserAction {
...
$flatPassword = $request->getParameter('password');
$cryptPassword = crypt($flatPassword);
...
$userValue->setPassword($cryptPassword);
...
...
$service->registerUser($userValue);
....
}
LoginAction {
...
$flatPassword = $request->getParameter('password');
$cryptPassword = crypt($flatPassword);
...
$service->searchUserByPassword($userId, $cryptPassword);
....
}
この部分のコストを抑えるために、パスワードの再設定を補助をする機能を用意してあるサイトもあります。俗に言う「秘密の質問」という機能です。この機能とは、ユーザがパスワードを忘れてしまった場合に、ユーザ自信がパスワードの再設定を行える機能です。実際何が行われるというと、ユーザはパスワードを設定するときに、パスワードとは別に「秘密の質問」と「その答え」を登録します。それは何かというと、その1ユーザにしか知り得ない情報を聞き出す質問と、それについての回答を登録させるのです。例えば「秘密の質問」に免許書番号と入力して答えに実際に自分の免許証に記載してある番号を「その答え」に登録します。パスワードの再設定が必要になったときには、ユーザにこの「秘密の質問」を表示します。そして、「その答え」の入力をデータベースに保存されているものを確認して、確認ができた場合は、パスワード再設定画面に進みます。このとき秘密の質問の答えも暗号化するように気をつけます。
この機能は便利かもしれませんが、セキュリティホールになる場合が多いです。まず、「秘密の質問」を選択肢にしているサイトがありますが、選択肢が単純すぎるケースがよくあります。母親の旧姓とか、ちょっと本人とさりげない会話をしてでも聞き出すことができてしまいます。ペットの名前なんて論外。「秘密の質問」自体、ユーザに入力させるサイトもありますが、これはかなりまずいです。頭の悪いユーザほど、頭の悪い質問を入力します。好きなサッカー選手とか、だいたい10回ぐらいでクラックできます。マイナーな選手だとしても、1/1000ぐらいの確立であたるような感じですよね?4桁の数字のパスワードでさえ、クラックされる率はそれより低い確率になります。この辺りは、登録される情報の機密性(?)、ユーザへの利便性、運営コストなどのウェイトをとって適切な判断をする必要があります。もちろん、これをシステム屋まかせにしないように!!
このような対策を行ったところで、内部により情報が漏れた場合は全くもって意味をもちません。実際に、情報漏洩も内部による犯行が多いわけですし。そういった場合の対策としては、データベースサーバのセキュリティの強化が必要です。アクセスするためには、1ユーザ(利用者・オペレーター)につき1アカウント作りましょう。また、データベースの中身に含まれる個人情報を可逆性のある処理で暗号化する事も可能です(MD5,RSAなど)。この場合はいちいちプログラムを使って復号をしないといけませんが、ウェブアプリケーションからすれば、それは簡単な実装です。データベースから直接データを吸い出されたときの対策になります。