こんにちは。
先日、脆弱性対策要員に抜擢され、いろいろと脆弱性対策について改めて考える機会が多くありました。
そこで今回は、脆弱性の中でも代表的(?)なSQLインジェクションについてまとめてみました。
SQLインジェクションとは
データベースと連動したWebサイトで、データベースへの問い合わせや操作を行うプログラムにパラメータとしてSQL文の断片を与えることにより、データベースを改ざんしたり不正に情報を入手する攻撃。また、そのような攻撃を許してしまうプログラムの脆弱性のこと。
–IT用語辞典より
SQLインジェクションというものを言葉にすると、そのものずばりな説明になります。
具体的にどういった事象かといいますと、
たとえば下記のようなテーブルがあったとします。
id | name | created | |
1 | 田中太郎 | tanaka@example.com | 2015-05-07 00:00:00 |
2 | 鈴木次郎 | suzuki@example.com | 2015-05-07 00:00:00 |
3 | 佐藤花子 | satou@example.com | 2015-05-07 00:00:00 |
また、下記のようなSQL文がプログラム内に書かれていたとします。
1 2 3 |
$id = $_POST['id']; $sql = 'SELECT id, name, mail, created FROM employee WHERE id = '.$id; //→このあとDBの接続処理・SQLの実行処理があります(割愛) |
このSQL文は、POSTされてきたidの値を元にして社員のデータをすべて表示する、というものです。
このSQLは指定されたidに対してのデータを表示する想定なので、例えばid=1をPOSTすると、
id | name | created | |
1 | 田中太郎 | tanaka@example.com | 2015-05-07 00:00:00 |
こちらのようなデータ出力が期待できます。
しかし、もしPOSTされたidの値に、
1 |
1 OR 1 = 1 |
といった値が入ってきた場合は、どうなってしまうのでしょうか。
SQL文は
1 |
$sql = 'SELECT id, name, mail, created FROM employee WHERE id = 1 OR 1 = 1'; |
と同様のものが実行されてしまい、こちらを実行すると
id | name | created | |
1 | 田中太郎 | tanaka@example.com | 2015-05-07 00:00:00 |
2 | 鈴木次郎 | suzuki@example.com | 2015-05-07 00:00:00 |
3 | 佐藤花子 | satou@example.com | 2015-05-07 00:00:00 |
のように、他の社員の情報まで見れてしまいます。
テーブルにはメールアドレスも入っていますので、これにより個人情報の流出につながってしまいます。
実際にやってみよう!
SQLインジェクションの概要をお話しさせていただきましたが、ここまでの話は割と理解されている方が多いのではないでしょうか。
しかし、脆弱性を真に理解するためには発生させてみるのが早いということで、SQLインジェクションについてのクイズを3問ほど用意させていただきました。
実際に脆弱性を発生させてよい環境を作るのがなかなか難しかったので、下記のクイズを通して仮想的にDBをのっとってみましょう!
【問題】
下記のような構造のテーブルがあります。
employeeテーブル
addressテーブル
employeeテーブルのidと、addressテーブルのemployee_idにはリレーションが張ってあります。(と思ってください。)
また、実行されるプログラムは、下記のものになります。
1 2 3 |
$name = $_POST['name']; $sql = 'SELECT id, name FROM employee WHERE name = \'%'.$name.'%\' AND created >= \'2015-05-01 00:00:00\''; //→DB接続、SQLの実行処理(割愛) |
このとき、下記それぞれの動作を実現させるためには、$_POST[‘name’]としてどのような値をPOSTすればよいでしょうか。
Q1.全社員のid、名前を取得する
Q2.employeeテーブル内のデータを全削除する
Q3.全社員の住所情報を取得する
3日後くらいに、これらの問題の解答例を載せたいと思っておりますので、お時間ある方は是非考えてみてください!
それでは!