これまではアプリケーション開発以前の基盤の話題を説明してきたが,今回からいよいよ具体的な設計・開発におけるセキュリティ対策について説明する。まずは,Webアプリケーションへの入力値の取り扱いについてだ。

 Webアプリケーションにおける「入力」とは,主にHTTPリクエストに含まれるクエリー文字列(Query Strings),POSTデータ(Post Data),クッキー(Cookie),その他のHTTPリクエスト・ヘッダー(Refererなど)といったものを指す。入力源としてはこれら以外にも,電子メール,ファイル,データベース参照などが挙げられる。

ぜい弱性はどこで発生するか

 具体的なセキュリティ対策の説明を始めるに当たって,ここで改めてWebアプリケーションの基本構造と,様々なぜい弱性がどこで発生するかを示しておこう。図1は,Webアプリケーションの動作を「入力/処理/出力」という古典的モデルに当てはめたものだ。

図1●Webアプリケーションの構造とぜい弱性発生個所
図1●Webアプリケーションの構造とぜい弱性発生個所

 例えば「処理」の不備としては,認証や権限管理(認可)の問題が挙げられる。「出力」にかかわる問題点には,SQLインジェクションやクロスサイト・スクリプティング(XSS)といった,HTML出力やSQL生成など「出力インタフェース」に関連したものがある。

 従来,セキュリティ対策としては「入力値のチェック」を推奨したものが多かったが,上記のようなぜい弱性の発生要因と問題個所から考えると,入力値のチェックでは根本的なぜい弱性対策にはなり得ない。このような根本対策をいち早く日本に普及させた解説文書として,情報処理推進機構(IPA)が発行している「安全なウェブサイトの作り方」がある。同書から,SQLインジェクション対策の項目を引用する(図2)。

■根本的解決
1)-1 SQL文の組み立てにバインド機構を使用する
1)-2 バインド機構を利用できない場合は,SQL文を構成するすべての変数に対しエスケープ処理を行う
2) Webアプリケーションに渡されるパラメータにSQL文を直接指定しない
■保険的対策
3) エラー・メッセージをそのままブラウザに表示しない
4) データベース・アカウントに適切な権限を与える
図2●「安全なウェブサイトの作り方」からSQLインジェクション対策の引用

 図2のうち,1)と3)は出力時の問題,2)は設計の問題,4)は設定の問題である。根本的対策・保険的対策ともに,入力値に関する言及はない。SQLインジェクション対策の基本は「どの文字も正しく処理できるようにSQLを発行する」ということだから,入力時点で特定文字を排除する処理は必要ないためである。

 つまりセキュリティ対策は,「処理」と「出力」の部分で実施するのが正しい。とは言え,「入力」に関しては何もする必要がないと考えるのは早計である。少なくとも,Webアプリケーションが最終結果として返すデータの信頼性を高めるためには,入力値の検証は欠かせない。そしてこれが,ユーザビリティの向上につながると同時に,セキュリティ上の「保険的対策」にもなる。

 アプリケーションの入力欄には大抵,文字種や文字数の制約がある。図3に示した個人情報入力画面を例に説明すると,郵便番号,電話番号などは,基本的に数値およびハイフンや括弧など一部の記号のみ許可される。郵便番号の7けた(3けた+4けた),クレジットカード番号の16けた(4けた×4)など文字数が決まっている場合も多い。入力があったとき,その文字種や文字数がアプリケーション仕様に合っているかどうかをチェックすれば,ユーザーの入力ミスを早期に検出することによりシステムの信頼性を高められる。さらに言えば,仕様外の内容を見付けて早期に再入力を促すことは,ユーザビリティの向上にもつながる。

図3●個人情報入力画面の例
図3●個人情報入力画面の例