星野君は赤坂さんと一緒にお客さんのWebアプリケーションの検査をすることになった。辛うじて「不必要情報」の脆弱性を見つけたものの、赤坂さんは不満げだ。
「だって、これ、ほかにもっと危険な脆弱性あるよ……」。
赤坂さん 「ってことで、今回は50点ってとこかな」
星野君 「うわっ。厳しいですね……。一応脆弱性は見つけたんだからもう少し……」
赤坂さん 「え。だって、これ、ほかにもっと危険な脆弱性あるよ」
(第8回 「メールアドレスの登録チェックが、余計なお世話に?」より)
星野君 「(ほかにも脆弱性あるっていってもなぁ……)」
赤坂さんに「ほかにもっと危険な脆弱性あるよ」と指摘されたにもかかわらず、星野君にはサッパリ見当が付かなかった。不必要情報(Unnecessary Information)の脆弱性に気付くまでの作業で、一通り思い付くことはやりつくしていた。
そうこうしているうちに時間は過ぎ、結局ほかの脆弱性を見つけられないまま、お客さんと約束した時間になってしまった。
赤坂さん 「もうお客さんに検査終わりましたってメールするよー?」
星野君 「あ、もう終わりの時間になっちゃったんですか……」
赤坂さん 「結局見つけられなかったんだね。ガッカリ」
星野君 「(うう……。けど、しっかりした作りしてたから、ほかに脆弱性があるとは思えないんだよなぁ……)」
赤坂さん 「何か気になる挙動とかなかった?」
星野君 「いや、特にこれといって……」
赤坂さん 「しょうがないなぁ。やっぱ、この脆弱性はちょっと難しかったのかなぁ……」
赤坂さんによると、今回のWebアプリケーションにはSQLインジェクションがあったようだ。これは、以前星野君が自社のWeb管理画面で見つけたような単純なパターン(第2回)ではなく、多少複雑なパターンであるため、星野君は見逃してしまった。
星野君 「SQLインジェクションなんてあったんですかー。全然気付きませんでした……。どこにあったんですか??」
赤坂さん 「星野君がさっき見つけたっていってた不必要情報の脆弱性と同じところだよ」
星野君 「え!?同じところ??」
赤坂さん 「そう、まったく同じところ。メールアドレスの重複チェックの部分」
星野君 「えええ!あそこは特に念入りにいろいろ試したのに……」
星野君は、メールアドレスの部分にさまざまな記号を入れて挙動を見たのだが、特にエラーが出てしまったり、画面の表示がおかしくなったりということは確認できなかった。
赤坂さんがSQLインジェクションを見破った手法
赤坂さん 「じゃあ、説明しようかな」
星野君 「はい。お願いします」
赤坂さん 「まず、メールアドレスの後ろに、『' and '1' = '0』っていう条件文を付けたらどういう挙動をするか分かる?」
星野君 「うーんと、『hoshino@example.co.jp' and '1' = '0』ってメールアドレスは登録されてないから、そのまま登録ができると思いますけど……」
赤坂さん 「そうだねー。挙動としてはそのまま登録の処理に移るね。じゃあ、メールアドレスの後ろに、『' and '1' = '1』っていう条件文を付けたらどうなると思う?」
星野君 「えっと、どうだろう……。SQLインジェクションができるってことは……」
赤坂さん 「この場合少し挙動が違って、『メールアドレスが重複しています』っていうメッセージが表示されるんだよね」
このWebアプリケーションでは、メールの重複チェックでSQLを呼び出している。メールアドレスをキーとして、データベース内を検索し、データベース内に一致するレコードがあった場合に重複と見なす、という作りだ。
具体的には、以下のSQL文でlogin_idを取得できた場合、メールアドレスが重複しているという判断を行う。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
この場合、すでにメールアドレスが登録されていれば、「メールアドレスが重複しています」というメッセージが画面上に表示される。
次に、メールアドレスの末尾に「' and '1' = '0」を追加した場合を考えてみよう。生成されるSQL文は以下のようになる。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
元の条件文の後ろに常に「偽」となる条件文が付いているため、条件文全体として偽という結果になり、重複チェックに引っ掛からないという形になる。従って、すでにメールアドレスが登録されていても、重複チェックには引っ掛からず、そのまま登録処理へ移ってしまう。
続いて、「' and '1' = '1」という文字列を末尾に追加した場合を考えてみよう。この場合、生成されるSQL文は以下のようになる。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
今度は元の条件文の後ろに常に「真」となる条件文が付いているため、条件文全体として前半の条件文「mail = 'hoshino@example.co.jp'」の結果が反映される形になる。つまり、(1)の場合と同じ結果になるのである。
これら(2)の式と(3)の式の挙動から、入力したSQL文がそのまま処理されてしまったということを知ることが可能になる。
Copyright © ITmedia, Inc. All Rights Reserved.