VAddyブログ

- 継続的セキュリティテストへの道 -

VAddyのSQLインジェクション検知ロジックを改良しました

ぼく:「数値入力欄にシングルクォートを入力するとデータベースエラーが!きっと妖怪のしわざだよ!」

執事(ジェンキンス):「まさかぁ、そんなことあるわけが…」
ぼく:「脆弱性を検査するのは執事の仕事。しっかり調べておいてよ!!」

ということで、ウェブアプリの脆弱性検査はJenkinsのようなCIシステムに統合されてしかるべきではないかというコンセプトの元、VAddyというサービスを開始しました。私は主にネタ担当…じゃなくてVAddyのコア部分であるプロキシ部分と脆弱性検査エンジンの開発を担当している金床(かなとこ)です。よろしくお願いします。(ちなみにtwitterアカウントは@kinyukaです。)

サービスを開始したばかりのVAddyですが、非常にうれしいことに既に多くのユーザの方がスキャンを試してくれています。そんな中、フィードバックとして目立ったのが、「SQLインジェクションに脆弱だと判定されるが、そうは思えない。たぶん誤検知では?」というものでした。

VAddyの(その時点での)SQLインジェクション検知ロジックは非常にシンプルなもので、

  • パラメータに、シングルクォートを付与してリクエストを送る
  • レスポンスのステータスコードが、正常時とは異なっており、かつ500以上であれば脆弱と判定する
  • あるいは、レスポンスに、正常時には存在しなかったデータベースのエラーメッセージが含まれていれば、脆弱と判定する

というものでした。

しかし、意外にシングルクォートを付けるだけでステータスコードが500になってしまうアプリケーションは多いようです。何人かのユーザの方の環境において「本来はSQLインジェクション脆弱性がないのに、脆弱と判定された」という現象が発生しました。

image

そこで、この度この部分のロジックを改良しました。現時点(2014/10/30)でのSQLインジェクション検知ロジックは次のようになっています。

  • パラメータに、シングルクォートを付与してリクエストを送る
  • (レスポンスに、正常時には存在しなかったデータベースのエラーメッセージが含まれていれば、脆弱と判定して終了)
  • レスポンスのステータスコードが、正常時とは異なっており、かつ500以上であれば、さらに次の処理をおこなう
  • パラメータが数値、例えば12345の場合には、abs(12345)のように、abs関数を呼び出す形のパラメータに書き換える
  • パラメータが数値でない場合には、シングルクォートを2つ付与する(例えばABCの場合には、ABC’‘とする)
  • 上記のリクエストを送信し、ステータスコードが500未満の場合には、脆弱と判定する

SQLインジェクション脆弱性が存在する場合には下記のような挙動が想定できます。

(数値の場合)

1'はエラーを起こす
abs(1)はエラーを起こさない

(文字列の場合)

ABC'はエラーを起こす
ABC’'はエラーを起こさない(2つ連続したシングルクォートはSQL文では1つのシングルクォートとして扱われる)

そのため、上記のようなロジックにしてみました。このようにすることで、とりあえず問題となっていた誤検知は回避できるようになったことを確認しています。

VAddyはクラウド型(SaaS)のサービスなので、今後も積極的に素早く検知ロジックを改善していく予定です。そのため上記ロジックについても、ブログには書いてみましたが、来月にはもう変わっているかもしれません。

VAddyの脆弱性検査エンジンは既存のツール(例えば、OWASP ZAP等)を使わずに、フルスクラッチで自社開発しています。この理由については長くなるため、また別のエントリとして書きたいと思います。

VAddyへのフィードバックはお気軽に@vaddynetまでお寄せください!