第9章 セキュアな実装
[9-3.]
エラーメッセージからの情報暴露
ユーザ入力の誤りについて詳細な情報を表示するのは親切な仕様であるといえる。しかし,ログイン処理でそれを詳細に表示することはパスワード破りの手がかりを与えることにつながる。また,ソフトウェアの内部構造を推定できるデバッグ情報がエラーメッセージに表示される可能性を見過ごしてしまうと危険である。



 PDF
● ● ●
親切なエラーメッセージ
ユーザからの入力データを扱う画面の典型的な例として,ユーザ登録を行う画面を用意した(画面1)。ユーザ自身に登録データを入力してもらうシステムの場合,たいていこれに似たユーザ登録画面があるだろう。
 
画面1では通常,名前や住所,メールアドレス,誕生年の入力をユーザが行うことになる。ここで何も入力しないまま「登録」ボタンをクリックしたときに表示されるエラーメッセージを画面2にのように想定してみた。ここの「○○○は必須項目です」「○○○には数字を入力してください」のように,入力の誤りを(あるいは入力しなかったこと自体を)詳細に表示することは,ユーザが入力の訂正をすみやかに行う助けになる。
 
すなわち,入力ミスの内容を詳細にエラーメッセージに表示するということはユーザの操作性の向上につながり,通常は推奨されている。
画面1 ユーザからの入力を扱う画面の例

 画面1 ユーザからの入力を扱う画面の例
画面2 画面1のまま「登録」ボタンをクリックした結果
 画面2 画面1のまま「登録」ボタンをクリックした結果
不適切な値が入力された各項目について詳細なエラーメッセージが表示されれば,ユーザはどの項目に入力した値がどのようなエラーを起こしているかを判断することができる。ユーザの入力操作を円滑に進めるための手法である
● ● ●
饒舌なログイン画面
では,ログイン処理を行う画面3のような場合はどうだろうか。ユーザ認証を伴うWebアプリケーションには必ずといっていいほど存在する画面である。
 
画面3は,システムに登録されて《いない》ユーザID「foobar」を入力しているところである。ここで「ログイン」ボタンをクリックした結果が画面4である。「ユーザIDが間違っています」と表示されている。
 
次に画面5は,システムに登録されているユーザID「administrator」と誤ったパスワード「sesame」を入力しているところである。ここで「ログイン」ボタンを押した結果が画面6である。今度は,パスワードが間違っているためにその旨のメッセージ「パスワードが間違っています」が表示されている。
 
画面4画面6はエラー内容を詳細に表示しているため,両者のエラーメッセージの違いを識別することで特定のユーザIDが実在するかどうかを第三者が推定できてしまう。不正侵入を試みる者はいくつかの入力を試して有効なユーザIDを見つけると,今度はパスワードを破りにかかるのである(画面7)。
画面3
ログイン画面に正しくないユーザIDを入力
 画面3 ログイン画面に正しくないユーザIDを入力
このような処理にも詳細にエラー表示させることが必要だろうか

画面4
画面3で「ログイン」ボタンをクリックした結果
 画面4 画面3で「ログイン」ボタンをクリックした結果
ユーザIDが間違っているため,その旨のエラーが表示されている
画面5
存在するユーザ名「administrator」を入力
 画面5 存在するユーザ名「administrator」を入力
「ログイン」ボタンをクリックした結果は画面6
画面6
画面5で「ログイン」ボタンをクリックした結果
 画面6 画面5で「ログイン」ボタンをクリックした結果
ユーザIDは存在するが,パスワードが間違っているため,その旨のエラーが表示されている
画面7 分かりやすいと各個撃破されてしまう
 画面7 分かりやすいと各個撃破されてしまう
不正侵入を試みる者は,まずユーザIDを推定し有効なものを見つけると,今度はそのアカウントのパスワードを破りにいく。そのため,画面4や画面6のようなエラーメッセージを表示するログイン処理は安全な設計とは言えない。
画面8 改善されたエラーメッセージ
 画面8 改善されたエラーメッセージ
画面3と画面5のどちらの状況で「ログイン」ボタンをクリックしてもこの表示が出るようにする。
ユーザIDとパスワードのどちらが誤っているのかが読みとれないエラーメッセージにすることで,部外者がユーザIDを推定することが困難になる。
ユーザIDの推定やパスワード破りには,よく使われる語のリストを順番に試す「辞書攻撃」や,全ての文字の組み合わせを試す「総当たり攻撃」などの手口がある。ユーザIDやパスワードの綴りが辞書や名簿に載っているものだったり,桁数が少なかったり,両者の綴りに関連があったりするものは。「破られやすいアカウント」である。そうした「弱い」アカウントが存在する上に,このような親切なエラーメッセージが出るとなると,ますます簡単にアカウントが奪われてしまうことになる。
改善されたエラーメッセージ
このように,ログイン処理においては必要以上に詳細なエラー内容を表示することはセキュリティ脆弱性となりかねない。では,ログイン処理においてはどのようなエラーメッセージが適切だろうか。
 
改善されたエラーメッセージの例を画面8に示す。これは,画面3画面5のどちらで「ログイン」ボタンをクリックしてもこの同じメッセージが表示されるというものである。安全でなかった画面4画面6と較べてみると,ユーザIDが間違っているのか,ユーザIDは正しいがパスワードが間違っているのか画面8の表示内容から判断できない。
● ● ●
処理系のエラーメッセージ
必要以上のエラーメッセージを表示することでシステム自体を危険にする例は,ログイン処理だけではない。使用しているソフトウェア製品が出力するエラーメッセージについても注意する必要がある。画面9にInternetInformationServices(IIS)のActiveServerPages(ASP)プログラム実行中に表示されたエラーメッセージの例を示す。
 
この問題への対策は,IISの設定画面を操作して,詳細なエラー情報をユーザが目にする画面に出力しないよう指定するというものである(画面10)。
 
画面9とその対策画面の画面10は,特定のWWWサーバ製品の例であるが,これはほかのWebアプリケーションプログラム稼働環境にも共通の問題である。また,Webシステム以外の開発においても開発環境,稼動環境に同様な問題がないか注意する必要がある。一般的に開発支援ツールはデフォルトで詳細なエラーメッセージを表示することが多い。
 
使用しているWebアプリケーションのサーバソフトウェアや稼動環境ソフトウェアの設定を見直し,もし詳細なデバッグ情報がユーザ向けエラーメッセージ中に露出するようになっていたら設定を変更するようにしよう。
画面9 プログラム内部構造の手がかりを与えるエラーメッセージの例
 画面9 プログラム内部構造の手がかりを与えるエラーメッセージの例
IISのデフォルトでは,ASPプログラムでのエラー発生時にこのような画面が表示される。この例では,当該ASPプログラムはSQL文を生成しており6行目でデータベースにアクセスしていること,パラメタcolはデータベースの列名に関係することが推定できてしまう。
画面10 WWWブラウザ向けエラーメッセージへの情報表示を抑制する
 画面10 WWWブラウザ向けエラーメッセージへの情報表示を抑制する
IISのASPの場合,インターネットサービスマネージャ(MMC)のWeb仮想ディレクトリの「プロパティ」の中の「仮想ディレクトリ」→「アプリケーションの構成」→「アプリケーションのデバッグ」→「スクリプトのエラーメッセージ」にて,「クライアントにテキストのエラーメッセージを送る」を選択することにより,ASP実行時エラーメッセージへの詳細な(過剰な)情報表示を抑制できる。
まとめ
不適切な入力データに対して表示するエラーメッセージが詳細なものであっても,セキュリティ上の問題とならないことは多い。しかし,ログイン処理においてはそうではない。エラーメッセージの表示のしかたによっては,ユーザIDがシステム上に存在するのかどうかを調べる手がかりを与えてしまうことがある。また,プログラムの稼働環境そのものがデバッグに役立つ情報として,ソフトウェアの内部構造を推定できる情報を出力してしまうこともある。ユーザ向けのエラーメッセージについては表示する情報を抑制することも考慮すべきである。