さて今回はSQLインジェクションの話。
名前のとおりデータベースに関する脆弱性です。
まずは例によって悪例から。
フォーム部分やSQL実行部分は書いていませんので適当なものがあると思ってください。
sqli.php
<!-- パスワードをチェックするプログラム --> $name=$GET['name']; $pass=$GET['pass']; $sql='SELECT * FROM user-data WHERE name='.$name.' and pass='.$pass; |
$nameでユーザ名を、$passでパスワードを取得して、
データベースと照合するという簡単なログインフォームです。
さて誰かがユーザ名「xxx」パスワード「yyy」でログインしてきた場合、
SQL文は次のようになります。
SELECT * FROM user-data WHERE name=xxx and pass=yyy
nameがxxxであり、passがyyyである人が検索されます。
想定通りに動作しました。
悪意のあるユーザがユーザ名「aaa」パスワード「aaa or 1=1 limit 1」
と入力したとします。SQL文は、
SELECT * FROM user-data WHERE name=aaa and pass=aaa or 1=1 limit 1
SQLではandのほうが優先されます。上のSQLは
SELECT * FROM user-data WHERE ( name=aaa and pass=aaa ) or 1=1 limit1
と解釈されます。
1=1は常に真なので、このSQL文は「user_dataテーブルの一番上の人の情報」を意味します。
ユーザ名もパスワードもわからないのにログインできてしまいました。
非常に重大な欠陥ですね。
さて、もっと悪意のある人が、
ユーザ名「aaa」パスワード「aaa;DELETE FROM user_data;」
と入力してきました。SQL文は、
SELECT * FROM user-data WHERE name=aaa and pass=aaa;DELETE FROM user_data;
user_dataテーブルが綺麗さっぱり消滅してしまいました。
こんなに簡単にわかる危険性でありながら、
対策を怠り被害に遭うサーバが後を絶ちません。
有名どころでは価格.com等も個人情報を盗まれています。
PHPでの対策としては、自力でエスケープもできますが、
対策を行ってくれるライブラリを使用するのが最も安全でしょう。
使用法はまたそのうち。
次回はセッション乗っ取りでも・・・と言いたいところですがちょっと理解しきれてないので微妙。
PR
トラックバック
トラックバックURL: