3月以来、世界中の多くのインターネットサイトが、悪意のユーザーによるSQLインジェクション攻撃に遭い、被害を出していることが報じられている。SQLインジェクションとは何か、またなぜこのように流行し被害が広がったのか、被害を防ぐにはどうすればいいのか、3回にわたり考えてみたい。
● SQLインジェクションとは何か
SQLインジェクションによる攻撃では、不正なスクリプトをWebサイトに埋め込むことで閲覧したユーザーのPCにウイルスを感染させたり、あるいはサーバーから不正に情報を盗み取られるというような被害が発生している。
通販サイトなどでは、攻撃により利用者のクレジットカード情報が盗み取られたことが発覚し、個人情報が漏洩したお詫びとして、ユーザーに対して金券や現金を配布することになったサイトもあるなど、その被害は金銭的にも大きくなっているようだ。
SQLインジェクションとは簡単に言うと、Webサーバーが使用しているデータベースを外部から不正に操作する攻撃だ。この攻撃により、データベースの内容を書き換えたり、意図しないデータをWebに表示させるといったことが可能になる。他のサイトからウイルスを読み込ませるようなHTMLタグを挿入したり、本来は表示されないはずの他のユーザーのクレジットカード情報を表示させるといったことができてしまうわけだ。
● SQLインジェクションを受けるサーバーの構成
では、なぜ、本来書き換えられてはいけない、データベースが外部から書き換えられてしまうのだろうか。
一般的に、SQLインジェクション攻撃では、URLやWebページに含まれるテキスト入力欄などに想定外のデータを送り込むことで、データベースの情報を改竄する。こうした攻撃が成り立つ理由について、まずはSQLインジェクション攻撃を受けるサーバーが、どのような構成となっているのかを見てみよう。
ここでは典型的なサーバー構成として、1)Webサーバー、2)アプリケーションサーバー、3)データベースサーバー――の3階層の構成を考える。まず、Webサーバーがインターネットからアクセスしたユーザーの要求を受け取る。アプリケーションサーバーは、Webサーバーが受けた要求をバックエンドに伝えたり、バックエンドからデータを受け取ってWebサーバーに受け渡す役割を果たす。そして、バックエンドにあるのがデータベースサーバーで、様々なデータを蓄積したり、蓄積したデータを検索してその結果を返すといった役割を担当する。
小規模なサービスの場合には、Webサーバー、アプリケーションサーバー、データベースは実際には1台のマシンで構成されていることもあるが、モデルとしては同様のものとなる。
この構成のサーバーに、ユーザーがアクセスしてきた時のデータの流れを見てみよう。例えば、オンラインショッピングサイトのアクセス時に、ログインしたユーザーの名前がWeb上に「ようこそ○○さん」といった形式で表示される場合を考えてみる。
まず、Webサーバーは利用者からのリクエストを受け付ける。そのリクエストをアプリケーションサーバーが判断し、ユーザーIDからユーザーの名前を検索せよとデータベースサーバーに命令する。データベースサーバーは、この命令に従ってユーザー名を検索する。
ここからはデータの流れは先ほどの反対になり、データベースサーバーは検索結果であるユーザー名をアプリケーションサーバーに返す。アプリケーションサーバーはユーザー名をWebページ中の「ようこそ○○さん」の部分に埋め込んでWebサーバーに返す。Webサーバーがこの内容をユーザーのWebブラウザに渡す。これにより、利用者の見ているWebページには、自分の名前が表示される。
さらに具体的なデータの流れを見てみよう。簡単な例として、以下のようにURLにユーザーIDが含まれる場合を想定してみる。
http://www.example.com?userID=20 |
WebサーバーはこのURLから「userID=20」の部分をアプリケーションサーバーに渡す。アプリケーションサーバーはこれを基に、データベースへの命令を作成する。この、データベースへの命令として一般的に用いられているのが、SQLという問い合わせ言語だ。
SQLとは、「Structured Query Language(構造化問い合わせ言語)」の略で、その名前の通り、データベースへの問い合わせに特化した構造にした言語だ。今回の例では、userIDが20のユーザーの名前を知りたいといった場合のSQLは、
SELECT userName from tableUserList where userID='20'; |
といった文になる。これをデータベースサーバーに渡すことで、データベースサーバーはuserIDが20のユーザー名を返す。例えば、そのデータが山田太郎さんであれば「山田太郎」という応答が返ってきて、これがWebクライアント上で表示される「ようこそ山田太郎さん」の「山田太郎」の部分になるわけだ。
|
Webサービスのサーバーは、Webサーバー、アプリケーションサーバー、データベースサーバーの3階層モデルで構成されている
|
● SQLインジェクションを引き起こす手順とは
前述のように、SQLインジェクションとは、Webページのテキスト入力欄やURLなどにSQL文の断片を埋め込むことで、データベースを改竄したり不正に情報を入手する手法のことだ。
SQL文を埋め込む手口は、先ほどの例で言えば、例えば以下のようなURLでアクセスすることによって行なわれる。
http://www.example.com?userID=20%27%20or%20%271%27%3d%271 |
URLの「?」以降の部分は、通常の文字で表記すると「userID=20' or '1'='1」となる。これをアプリケーションサーバーのプログラムが何も考えずに作られていると、以下のようなSQL文となってデータベースサーバーに伝えられてしまう。
SELECT userName from tableUserList where userID='20' or '1'='1'; |
このSQL文がどのような意味をもつかというと、「『userID=20』または『1=1』の条件が成り立つユーザーの名前を表示しろ」と命令していることになる。しかし、「1=1」は常に正しいので、この条件はどんなときにも成り立つ。つまり、登録されている全ユーザーがこの条件にあてはまってしまうことになる。
従って、この命令を受けたデータベースサーバーは、例えば「相生怜相本愛華麻生慶介……」のように全ユーザーの名前を返答してしまう。これがアプリケーションサーバーからWebサーバーに渡されて、「ようこそ相生怜相本愛華麻生慶介……さん」といった形でリストに載っている全ユーザーが表示されてしまい、情報漏洩が発生する。同様に、埋め込むSQL文を変えれば、データベースの内容を書き換えるといったことも可能になってしまうわけだ。
|
URLなどにSQL文の断片を混ぜることで、アプリケーションサーバーやデータベースサーバーに錯誤を起こさせ、想定しない動作を引き起こす。これが、SQLインジェクションの基本的な仕組みだ
|
SQLインジェクション攻撃を受ける原因は、プログラムのミスにある。先ほどの例で言えば、「userID=20 'or '1'='1」といった文字列を何も考えずにそのままSQL文に埋め込んでしまったことが、意図しないSQL文を実行されてしまう結果を生んでいる。
3月以来、大量に起きているSQLインジェクション攻撃でも、Webサーバーに対して
userID=;DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x4400450043004…… |
といったような文字列を渡すことが特徴となっている。この文字列は、「DECLARE」以降のSQL文を実行させることをもくろんでおり、データベースを不正に書き換える、あるいは全テーブル内容を表示させるなどの内容を実行させようとするようなSQL文がエンコードされて入っている。
大量に起きているSQLインジェクション攻撃では、このようなコマンドを自動に送り込むツールなどが用いられ、サーバーへの攻撃が試されているようだ。
次回は、こうしたSQLインジェクション攻撃がなぜ流行しているのか、その背景について解説する。
( 大和 哲 )
2008/05/14 12:15
- ページの先頭へ-
|