2/14の日記不適切な脆弱性サンプル - ockeghem(徳丸浩)の日記にも書いたが、ITproのSQLインジェクション解説記事脆弱性を利用した攻撃手法(4) --- SQLインジェクション | 日経 xTECH(クロステック)のサンプルがおかしい。脆弱性の危険を指摘するはずのところが、そもそもの仕様が脆弱なために、SQLインジェクションの有無にかかわらず任意ユーザのパスワードが変更できるという危険性に変わりがない。

SQLインジェクションのサンプルでは私も苦労した記憶がある。私が日経オープンシステム誌2001年7月号と8月号にWebアプリケーション脆弱性の解説を寄稿したころ、既にSQLインジェクションに関する情報はWebサイトなどにもあった。しかし、従来指摘されていたサンプルは、十分なものでないと感じていた。

そのころ指摘されていた悪用パターンには、以下のようなものが多かった。

"SELECT * FROM T_USER WHRER TID='$tid'"

このようなSQLがあったとして、$tidに以下のような値を入れてやる。

';DROP TABLE T_USER --

すると、

SELECT * FROM T_USER WHRER TID='';DROP TABLE T_USER --'

ごらんのように、SELECT文の後ろに、セミコロンをはさんで、他のSQLを追加し、ダブルハイフンによって余計なシングルクォートを無効にしてやる・・・というものである。

しかし、私は、このサンプルは次のような点で物足らないと感じていた。
それは、実際に上記を試してみると、環境依存により動いたり動かなかったすること、試した範囲では動かない場合が多かったことである。このようなサンプルでは、読者が実際に試してみて危険性を実感できることが望ましいが、その点で不十分であった。

このため、独自に、より望ましいサンプルを考えようと思った。望ましいサンプルが満たすべき要件は次のようなものであった。

  1. さまざまな環境で実際に動作すること
  2. 現実的に「ありそうな」例であること
  3. 危険性がわかりやすいこと

そのようなサンプルをあれこれ考えた結果、思いついたものが以下のサンプルである*1

SELECT PASSWORD FROM T_USER WHERE ID='$id' AND PASSWORD='$password'

ここで、
$id='TOKUMARU';
$password="' OR 'A'='A";

とすると、先のSQLは、

SELECT PASSWORD FROM T_USER WHERE ID='TOKUMARU' AND PASSWORD='' OR 'A'='A'

となり、パスワードを知らなくても、認証が通ってしまう。
このサンプルは、上記の三条件を満足している。実際、私は当時は脆弱性診断を担当していなかったが、その後現実のアプリケーションを診断してみると、上記のパターンが成立したケースはずいぶんとあった。その意味で、まさに「現実的に『ありそうな』例」であったのだ。

ところで、前述のようにこのパターンは独力で考え出したものであるが、その後このパターンはずいぶん有名になった。海外の文献など十分調べたわけではないので、どなたかこのパターンの初出をご存知の方は教えていただきたい。

*1:寄稿時はJava言語による記述であったがここでは簡単のためPerl風に改めた