31. SQLインジェクションの見つけ方の例-その2-
送信した値ごとの応答結果の差分を見て判定したりもする。
SELECT * FROM member WHERE name = 'tanaka' AND 'a' = 'a';
条件式が真
送信値:tanaka' AND 'a' = 'a
構成されるSQL文
検索結果:1件
田中
SELECT * FROM member WHERE name = 'tanaka' AND 'a' = 'b';
条件式が偽
送信値:tanaka' AND 'a' = 'b
構成されるSQL文
検索結果:0件
なし
SELECT * FROM member WHERE name = 'tanaka' BND 'a' = 'a';
文法として逸脱しているもの
送信値:tanaka' BND 'a' = 'b
構成されるSQL文 エラー
33. 例えばor条件だと
UPDATE member SET password = 'xxxx' WHERE id = 1;
本来の意図する処理
受け渡す値:1
UPDATE member SET password = 'xxxx' WHERE id = 1 OR 1 = 1;
カラム名「id」が1の値となっているレコードのみ、カラム名
「password」の値をxxxxに更新する
or条件のSQL文の断片を渡した場合
受け渡す値:1 OR 1 = 1
全てのレコードのカラム名「password」の値をxxxxに更新するこ
とになってしまう!
34. 複文もヤバい場合がある
UPDATE member SET password = 'xxxx' WHERE flag = 1 AND id = 1;
本来の意図する処理
受け渡す値:1
カラム名「flag」が1の値かつカラム名「id」が1の値となっているレ
コードのみ、カラム名「password」の値をxxxxに更新する
複文となるSQL文の断片を渡した場合
受け渡す値: 1; SELECT 1;--
カラム名「flag」が1の値となっている全てのレコードのカラム名
「password」の値をxxxxに更新することになってしまう!
UPDATE member SET password = 'xxxx' WHERE flag = 1; SELECT 1;-- AND id = 1;
45. そうであればこうなる
SELECT * FROM member WHERE id = 'test@vultest.com'+'' AND birthday = 1999523;
UPDATE member SET password = 'リセットするパスワード値' WHERE id = 'test@vultest.com'+'';
下記値をリマインダ機能で入力した場合
メールドレス:test@vultest.com'+' 誕生日:1999年5月23日
カラム名「birthday」の値 が1999523に該当するユーザのレコードが検索結果として返る
結果、全ユーザのパスワードが初期化される
メールアドレスと誕生日の値が一致するユーザがいるか検索
該当するメールアドレスのユーザのパスワードを初期化
※試しに同様の動きをするWebアプリを作ってみましたが、見事に再現されましたw