図 Webアプリケーションを攻撃する「SQLインジェクション」
図 Webアプリケーションを攻撃する「SQLインジェクション」
[画像のクリックで拡大表示]

 行きつけのショッピング・サイトが,不正アクセスを受けて突然閉鎖してしまった。まったく違うページが表示されるようになり,アクセスしたエンドユーザーの一部はウイルスに感染したらしい——。Webサイトにこうした被害をもたらす攻撃手法が「SQLインジェクション」である。

 SQLインジェクションとは,Webサーバーへの攻撃手法の一つである。「SQL」はデータベース操作用の言語で,「インジェクション」は「注入」という意味。つまりSQLインジェクションは,Webサーバーの背後で動くデータベースにSQLコマンドを送り込み,そのコマンドを実行させる攻撃方法を意味している。

 データベースを利用したWebサーバーは,エンドユーザーから送られてくるデータを受け取ると,それを基にSQLコマンドを作り上げる。そして,データベースにアクセスして該当する情報を引き出し,Webページを作ってユーザーに見せる。

 受け取ったデータからSQLコマンドを作成するときの変換処理は,単純なケースが多い。Webサーバー側にあらかじめ空欄のあるテンプレートを用意しておき,その空欄にWebブラウザから受け取ったデータを埋め込むといった処理が一般的だ。テンプレートには,テーブルからデータを選択させる「SELECT」や,参照するテーブル名を指定する「FROM」といった命令を記述しておく(図)。図の例でいうと,「SELECT * FROM USR WHERE ID='□';」がテンプレートだ。意味は,USRテーブルから(FROM USR),IDが「□」のもの(WHERE ID='□')の全項目を表示せよ(SELECT *)——となる。この「□」の部分にWebブラウザから送られてきた値を埋め込み,データベース管理システムに送る。

 しかし,実はここに落とし穴がある。クラッカがWebブラウザで例えば「K07' OR 'A'='A」と入力すると,Webアプリが生成するSQLコマンドの条件部分が「WHERE ID='K07' OR 'A'='A'」となり,データベースのすべてのレコードを返せという意味の指示になる。こうなると,データベースのすべての情報を取り出されてしまう。

 しかも悪いことに,SQLコマンドは「;」で区切ることで,異なる操作命令を続けて記述できる。つまり,クラッカが追加した操作命令で,Webアプリの背後のデータベースを好き勝手に操作されてしまうのだ。個人情報が抜き取られるだけでなく,勝手に注文されたり,取引残高を書き換えることも可能になる。

 SQLインジェクションを防ぐには,Webブラウザから入力された値をチェックし,SQLインジェクションのために送られてきた値をブロックする「サニタイジング」という処理を施せばよい。サニタイジングの具体的な方法には,(1)Webアプリで入力されたパラメータの長さや構成要素をチェックする,(2)SQLで特別な意味を持つ文字をチェックする,(3)SQLであらかじめ決められた変換規則に従って文字を変換する——といったものがある。