【日能研 個人情報流出】SQLインジェクションについて解説
最近よくフィッシングメールといったいわゆるサイバー犯罪が増えてきました。
そして最近話題になったのが日能研がSQLインジェクションの被害にあり、個人情報を28万件流出させてしまった事件。
www2.nichinoken.co.jp
SQLインジェクションって何?と思う方も多いと思うので簡単なプログラムと共に説明したいと思います。
まずSQLインジェクションのSQLとはデータベースを操作するための言語です。
データベースは情報を記録する箱というイメージ。
この箱であるデータベースに対して、SQLを使ってデータを追加したり、読み取ったり、更新、削除します。
SQLインジェクションは、このSQLを悪用して情報を入手したり、不正ログインを可能にします。
具体例
今回はそんなSQLインジェクションの被害に遭うような全くセキュリティ対策がされていないコードを書いてみました。
名前とパスワードを入力してログインするだけのシステム。
この後実際にSQLインジェクションを行い、パスワードなしでログインしてみます。
用意するデータベースのテーブルはこんな感じ
nameとpasswordが合致したら
ログイン成功画面にリダイレクトする仕組み↓。
ログイン処理で使うSQL文
SELECT * FROM student where name ='$name' and password = '$password'
例) ユーザーがnameに山田太郎、passwordにtaroyamadaと入力した際にプログラム上で実行されるSQL文
SELECT * FROM student where name ='山田太郎' and password = 'taroyamada'
この$nameと$passwordには上記画像のフォームからユーザーが入力した値が入ります。
whereとは条件を指定する際に使い、andはかつという意味で、データベースのnameの値かつpasswordの値が一致する行を探し、その行を返します。
つまり行の情報が返されたらログインが成功というわけです。
実際にSQLインジェクションを行う
名前に山田太郎、そしてパスワードの部分に' OR '1' = '1と入力
ログインボタンを押すと、、、
ログイン成功画面が出てきました。
パスワードが全然違うのに何故でしょう。
この時実行されるSQL文
SELECT * FROM student where name ='山田太郎' and password = '' OR '1' = '1'
このORは'または'という意味。ANDは'かつ'という意味。つまり上記のSQL文は
名前が山田太郎かつパスワードが'' または'1'='1'の時はログイン成功とするという意味になります。
このようにSQLの知識が少しあれば、誰でもSQLインジェクションを起こすことが可能です。
このようなSQLインジェクションを防ぐためには、プログラム側でユーザーの入力した値に対してエスケープ処理など様々な対策を行わなくてはいけません。
今回のセキュリティー対策がされていないコード
phpで書きました
//ログイン処理 if($_POST['name']!=''&&$_POST['password']!=''){ //入力された値を変数に入れる $name = $_POST['name']; $password = $_POST['password']; //ログイン処理 //ログインが2つの値と一致する行があった場合にログイン成功とする //不正ログイン // ' OR '1' = '1 $count = $db->query("SELECT * FROM student where name ='$name' and password = '$password' "); if($count->fetch()){ header('Location:userpage.php'); exit(); }else{ echo 'ログイン不成功!'; } } ?> <form action="" method='POST'> 名前:<input type="text" name="name"> パスワード:<input type="text" name="password"> <input type="submit" value="ログイン"> </form>
感想
SQLインジェクション恐るべし、、、