PEAK XOOPS - 大きな傘のSQL Injection版 (4) in englishin japanese

Archive | RSS |
XOOPS
XOOPS : 大きな傘のSQL Injection版 (4)
Poster : GIJOE on 2009-01-23 05:47:03 (18230 reads)

in englishin japanese
(3)で完成したと思っていたDBLayer Trapping anti-SQL-Injectionのロジックですが、これを実際にXOOPS 2.0.16a-JPでテスト運用してみたら、一般設定の更新でSQL Injectionの誤検出が発生しました。(具体的には、picoの共通ヘッダとしてダブルクオーテーションを含む文字列をポストする時)

このSQL対策ロジックは原理上、誤検出も当然あり得るのですが、どう見てもそういうパターンでもないので、疑問に思いながらXOOPSのソースを追ってみたら、かなりビックリするコードを見つけました。

class/database/mysqldatabase.php


    function quoteString($str)
    {
         $str = "'".str_replace('\\"', '"', addslashes($str))."'";
         return $str;
    }

ん? \"を"に書き戻している? なぜ?

ほとんどの文字列表現実装系で、シングルクオーテーションの内側でも"はエスケープの対象になると思いますし、実際、MySQLの文字列表現もそうなってます。なぜXOOPSのquoteString()がなんでこんな怪しいことをしているのか理解に苦しみますが、結果的に文字列のパースに間違いが出たこともなかったので、誰も突っ込まなかっただけなのでしょう。

いずれにせよ、このメソッドの正解は以下のコードです。

    function quoteString($str)
    {
         $str = "'".str_replace('\\"', '"', addslashes($str))."'";
         $str = "'".mysql_real_escape_string($str)."'";
         return $str;
    }

MySQL用のDBレイヤーなのですから、mysql関数が堂々と使えますし、逆に、MySQLのクライアントエンコーディングがSJISやBIG5にならない、なんて判断はこのメソッドには出来ないわけですから。

ふと気になって、ImpressCMSと本家版2.3.2を調べてみたら、どちらもちゃんとmysql_real_escape_string()を使う実装になってました。おそらくその変更タイミングは、本家版の2.0.14〜17あたりでしょうか。

つまり、XOOPS Cubeプロジェクトだけが取り残されている状況だったんですね

ただ、いずれのコアを使う場合であっても、今回と同様の誤検出は考えられるので、Protector-3.3.1では、以下のようなロジックを追加導入しました。

「'や"を含んだリクエストが、SQL内にエスケープされていない状態で含まれていたとしても、そのリクエスト全体が、SQLの文字列内に収まっている(=クオーティングを破っていない)ならSQL Injectionではない」

これで誤検出そのものも減りそうです。

0 comments

Related articles
Printer friendly page Send this story to a friend

Comments list

Login
Username or e-mail:

Password:

Remember Me

Lost Password?

Register now!