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

Archive | RSS |
PHP
PHP : 大きな傘のSQL Injection版(1)
Poster : GIJOE on 2009-01-07 04:37:49 (13354 reads)

in englishin japanese
XOOPSに限らず、いろいろなPHPアプリケーションで、今でもちょくちょくSQL Injection脆弱性が出てきます。それもケアレスミスです。

もちろん、ケアレスミスは人力では根絶不可能であり、SQLを文字列として生成すること自体をやめて、パラメータ方式で呼び出すべきだ、という方が本質的な議論でしょう。

ただ、オープンソースの世界では、自分の考えを他者に押しつけることはできませんし、SQL Injectionの可能性ある「誰か」の書いたコードを一切利用しない、というのも現実的ではありません。

事実として、SQL InjectionはXSSとは比べものにならないくらい恐い攻撃です。もし私がオープンソースアプリケーションで構築された特定のサイトを攻撃するとしたら、最初に狙うのはSQL Injectionでしょう。なぜならXSSやCSRF、セッション関連の攻撃と違い、即座に直接攻撃可能だからです。(さすがにコマンドインジェクションとかRFIはない、という前提で)

そういうわけで、Protectorでは、SQL Injection対策っぽいものも入っているのですが、私自身、あまり役に立っている気がしません。攻撃者がProtectorの対策コードを読めば、明らかに抜け道だらけです。(本当に役に立ったとすれば「最後にidのつくリクエスト変数名について強制的にintval()をかける」くらいでしょうが、これも副作用が大きすぎます)

強力なSQL Injection対策ができない理由は簡単で、本当に必要なリクエストかどうか区別がつかないからです。「UNIONをUNI-ONにする」なんてのも、本当はあってはならないことです。UNIONという単語を使ったまともな投稿が勝手に書き換わってしまいます。

ただ、入口であるリクエスト層だけで判断している以上は、ここが限界となりますが、大きな傘anti-XSSシステムと同様、入口と出口の両方を押さえれば、かなり有力な手段となることにふと気がつきました。これはいけそうです。

anti-XSSでは、出口はobフィルターでした。XSSになる可能性があるリクエストがある時のみob_start()をかけて、出力にリクエストがそのまま含まれるようならXSSとして停止する。

これをanti-SQL-Injectionにあてはめると、出口は当然クエリ関数(メソッド)となります。SQL Injectionになる可能性があるリクエストがある時のみ、DBレイヤーを乗っ取って、クエリ本文(クオーテーション外)にリクエストが含まれるようならSQL Injectionとして停止する…

…とまあ、文章として書くのは簡単なのですが、SQL Injection用の出口処理は結構面倒です。SQLをちゃんとパースする必要がありますから。

また、この仕掛けをXOOPS用Protectorとして採用する場合、もう一つ問題があります。それは、現状のDBレイヤーは、途中で乗っ取ることが不可能、ということです。この点は、コア側に対応してもらう必要があるため、別エントリにしたいと思います。


ちなみに、今回私が考え出した(と思っていた)方法ですが、元ネタがあったのを思い出しました。
「本質的なSQL Injection対策のためにはDBレイヤーを乗っ取るしかない」
と、もう4年も前にJM2さんが指摘していました。流石としか言いようがありません

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!