SQL Injectionとは?
Webのデータはすべてデータベース(DB)に格納されています。そもそも、SQLとは「Structured Query Language」の略で、データベース上で下記の操作を行うために使用される言語のことをいいます。- データの追加
- データの更新
- データの削除
- データの検索
- テーブルの作成
- テーブルの削除
- テーブルの主キーの設定
- ユーザ権限の付与
$name = '\' OR 1 = 1; OR 'A' = A 1 or '1' = '1';
SQL Injectionが悪用される理由とは?
一般的に、WebサイトのユーザID・パスワード入力では文字列しか入力しません。しかし、脆弱性があるWebサイトの場合、上記のようなSQL文を含む文字列を命令文として認識させることができるのです。そのため、データベースが自由に操作されてしまいます。そして、悪意のある攻撃者がSQL Injectionを悪用する理由は、データベースで個人情報を閲覧したり盗み出したり、データベースの変更・消去といった悪質な行為を行うためです。 それでは、実際に社員データを出力するプログラムをもとに、SQL Injectionを実践してみましょう。 例えば、下記のようなテーブルがあったとします。id | name | created | |
1 | 一郎 | ichirou@example.com | 2021-06-05 00:00:00 |
2 | 二郎 | jirou@example.com | 2021-06-05 00:00:00 |
3 | 三郎 | saburou@example.com | 2021-06-05 00:00:00 |
$id = $_POST['id']; $sql = 'SELECT id, name, mail, created FROM employee WHERE id = '.$id;
このSQL文は、POSTされたidの値を元にして社員のデータをすべて表示するプログラムです。 例えば、id=1をPOSTすると、下記のデータが出力されます。id | name | created | |
1 | 一郎 | ichirou@example.com | 2021-06-05 00:00:00 |
1 OR 1 = 1
SQL文は、$sql = 'SELECT id, name, mail, created FROM employee WHERE id = 1 OR 1 = 1';
と同様のものが実行されてしまいます。そして、このSQL文を実行すると、下のように他の社員の情報まで出力されてしまいます。これを悪用すれば、「SQL Injection」で個人情報を閲覧できます。id | name | created | |
1 | 一郎 | ichirou@example.com | 2021-06-05 00:00:00 |
2 | 二郎 | jirou@example.com | 2021-06-05 00:00:00 |
3 | 三郎 | saburou@example.com | 2021-06-05 00:00:00 |
SQL Injection攻撃の脆弱性を2つのポイントで解説!
WebサイトがSQL Injectionによる攻撃を受ける場合、その目的として多いケースが「Webサイトの改ざん」と「個人情報の漏えい」の2つです。Webサイトの改ざん
脆弱性のあるWebサイトにSQL Injectionを用いることで、そのコンテンツから接続するデータベースに、管理者・開発者の意図しないプログラムを書き込み、改ざんすることが可能です。SQL Injectionによって、Webサイト上に表示されるテキストが改ざんされたり、挿入した覚えのない画像が表示されてしまうなど、コンテンツが不正に変更されるケースも少なくありません。また、被害だけでなく、改ざんしたWebサイトを閲覧したユーザが、マルウェアなどの不正なプログラムに感染する被害が継続的に発生しています。Webサイト改ざんによる被害はそれだけではなく、不正改ざんによってGoogleに危険なサイトと判断されてしまえば、検索順位が大きく下がってしまったり検索結果からの除外されてしまったりする可能性があります。個人情報の漏洩
SQL Injectionで、データベース内のユーザIDやパスワード・クレジットカードの番号などの重要な個人情報を抜き取ることも可能です。2011年にSONYのゲーム用のサービス「PlayStation Network」を利用しているユーザ情報が漏洩したことがありますが、「SQL Injection」攻撃によることが原因でした。抜き取られた情報のなかには、「会員の氏名」、「住所」、「メールアドレス」、「生年月日」、「会員ID」、「パスワード」などが含まれていたといわれています。必須!SQL Injection攻撃を防止する3つの対策とは?
SQL InjectionによるWebサイト攻撃は、しっかりと対策をすれば防止できます。今回紹介する対策方法は、下記の3つです。対策① WAFの導入
SQL Injectionを悪用した攻撃への対策の1つに、WAFの導入が挙げられます。WAFとは「Web Application Firewall」の略で、分かりやすくいえばファイアウォールの1種。その特徴は、直接管理・改修することができないWebアプリケーションを攻撃から守ってくれます。導入すれば、Webアプリケーションを用いたネットショッピングやゲーム、インターネットバンキングなどのWebサービスが保護できます対策② 脆弱性診断によるチェック
Webサイトの脆弱性は、自分ではなかなか判断できません。そのため、セキュリティ診断サービス・脆弱性診断サービスなどを活用して、Webサイトやクラウドサービス上でさまざまなサービス提供を実現するWebアプリケーションの脆弱性の有無をチェックする必要性があります。ちなみに、脆弱性診断サービスには有償のものと無償のものがあります。無償だと費用をかけずに脆弱性診断ができますが、ある程度の知識が必要となります。 そもそも、脆弱性があるとSQL InjectionによるWebサイト攻撃は防止できないため、費用がかかっても脆弱性診断をしておくことはおすすめです。対策③ エスケープ処理
エスケープ処理は、SQL Injection攻撃における対策の基本です。そもそもエスケープ処理とは、プログラム中で使用する特殊な記号を意味の繋がらない文字として扱う処理のことです。プログラム言語は、記号に特殊な意味を持っていることが多く、そのプログラム言語の特殊性が悪用されてSQL Injection攻撃を受けます。 エスケープ処理をしておけば、WebサイトがSQL Injectionによる攻撃を受けても、入力した言語がプログラム言語ではなく意味を持たない言語として認識されため、被害を防ぐことができます。SQL Injectionにおける対策方法の実例
今回は、SQL Injectionによるデータベースへの問い合わせを実行するプログラムの実例です。プログラム内に脆弱性があり、そこからSQL Injection攻撃を受けますが、その対策方法についても実例で紹介しています。それでは、ユーザ名ごとに情報が分けられているデータベースから、指定したユーザ名に一致する情報を指定する下記のSQL Injectionを例に解説していきます。SELECT * FROM items WHERE owner = <userName> AND itemname = <itemName>;
対象とするプログラムはこちら。「C#」でのコードを例にしています。string NameA = ctx.getAuthenticatedUserName(); string valueA = “SELECT * FROM items WHERE owner = ‘” + NameA + “‘ AND toolname = ‘” + ItemName.Text + “‘”; nsda = new SqlDataAdapter(query, conn); DTd = new DataTable(); nsda.Fill(dt);
SQLで「USER」の情報を出力。しかし、下記コードには脆弱性がみられます。 ここに「OR ‘z’=’z’」を追加することで、WHEREを常に真にして、正しいユーザIDとパスワードを入力することなく、データベースにアクセスが可能になります。SELECT * FROM items WHERE owner = ‘USER’ AND toolname = ‘name’ OR ‘z’=’z’;
また、「OR ‘z’=’z’」はtoolnameの値に関係なく、検索条件が真として成立してしまい、toolnameが常に返ってきます。そのため、ログインを許可されていないユーザでもログイン可能な状態になってしまいます。 これにより、USERの情報だけではなく、itemsテーブルに格納されているすべてのデータを操作が可能。結果として、下記のSQLと同じ処理が行われます。SELECT * FROM items;
ちなみに、SQLでは、ユーザIDとパスワードの組み合わせは、次のような形でチェックされます。SELECT*FROM tableA WHERE user=’USER′ and pass=’PASSWORD′;
しかし、C#の例と同様に「’or’1’=’1」を使うことでユーザ認証を回避できます。WHERE user=’USER′ and pass=”PASSWORD”or’1’=’1′;
同じように、以下のようなSQL文を使うことでデータの消去も可能です。name’; DELETE FROM items; SELECT * FROM items WHERE ‘a’=’a