Part2では,Webアプリの背後にあるデータベースを好き勝手に操作できるSQLインジェクションの手口と,Webアプリケーションに「サニタイジング」という処理を追加するといった防止策について見ていく。
続いて「SQL(エスキューエル)インジェクション」を見てみよう。
データベースを好き勝手に操作された
クラッカがSQLインジェクションに成功すれば,Webアプリの背後にあるデータベースを好き勝手に操作できる。Webアプリでデータベースの内容を更新しないようにしていても,その制限はSQLインジェクションに対しては働かない。
データベースを好き勝手にされた結果,エンドユーザーに表示されるWebページが改ざんされてしまうことは珍しくない。Webサイトによっては,動的に生成するWebページの部品をデータベースに保存し,Webアプリがユーザーからの情報と合わせてWebページを作ることがよくあるからだ。クラッカがWebページの部品を改ざんしてウイルスへのリンクを貼り付ければ,エンドユーザーにウイルスをばらまくこともできる。
テンプレートに値を埋め込む
SQLインジェクションを理解するためには,まず正常な状況でWebアプリがデータベースを利用するしくみを押さえておく必要がある(図1)。
正常なアクセスでは,エンドユーザーが入力したデータは,「UID=K07」(ユーザーIDがK07)といった格好でHTTPリクエストの中に入れられる。Webアプリは,このデータをHTTPサーバー経由で受け取り,データベース操作命令に変換する。多くのWebアプリは,データベース操作命令をSQL言語に従ったSQLコマンドとして実行する。
たいていのWebアプリが実行するSQLコマンドへの変換処理は,極めて単純だ。あらかじめ空欄のあるテンプレートを用意しておき,その空欄にWebブラウザから受け取ったデータを埋め込むだけである。
Webアプリは,データベース操作の大まかな部分をテンプレートとして用意することが多い。テンプレートには,テーブルからデータを選択させる「SELECT(セレクト)」や,参照するテーブル名を指定する「FROM(フロム)」といった命令を記述しておく。こうした命令で構成したテンプレートに,Webブラウザからパラメータとして受け取った文字列や数値をはめ込む。
図1の例で見てみよう。Webアプリは,「SELECT * FROM USR WHERE ID='';」というテンプレートを用意しておく。意味は,USRテーブルから(FROM USR),IDがのもの(WHERE ID='')の全項目を表示せよ(SELECT *)――となる。の部分にWebブラウザから送られてきた値を埋め込み,データベース管理システムに送る。