石橋秀仁です。渡辺さん、提案ありがとうございます。

WATANABE Tetsuya <tetsu / jpn.hp.com> wrote:

> 渡辺哲也です。

> 今回については Ruby なので、動的に 
> SQL 生成することが可能なので、#{} 
> を使うので対応してはいかがでしょう?

そうですね。#{}で展開する変数が数値と分かっているとき、
自分用に作るときなどは、よくそのようにしています。

とはいえ、今回のケースでは、webアプリケーションの
部品として使うから変数の束縛を使いたいのです。


#以下、渡辺さんには既知の話だと思いますが・・・
#WEB-DB連携アプリの開発ばかりをやってる立場で・・・
##最近はクッキーを使わないフリーメールサイトの危険性が話題ですね。


SQLで文字列を想定しているところに#{}を持ってきたとき、
SQL文として意味のあるような文字列を渡すと、
いろいろ悪いことができてしまいますよね。

正しいエスケープをしなければ危険です。
もちろん正しくエスケープすればよい話です。
しかし、(1)面倒くさい^^;、(2)多重の防御策を用いるべき、
(3)見落としの可能性も考慮して間違いの少ない方法を、
という理由で、あまり#{}の方式は使わないように心がけています。


「極端な」例では
  sql = "DELETE * FROM FOO WHERE BAR=#{bar}"
というコードで(FOO.BARはNUMBER型で)、barが
  0 OR BAR IS NOT NULL
という内容だったりすると危ないと思います。

もちろん外部の入力のチェックは何重にも行うべきです。
その一つとして、変数のバインドは有効だと考えます。
目的は「Stringが単一の文字列として解釈される」ことです。
その反対に、望ましくないのは「SQL文中で文字列を想定して
#{}と書いた部分で、%w( ' , ; ) を含む文字列が、
単一の文字列と解釈されなくなってしまう」状態です。

#古い例え:
#system("/bin/ls #{$1}")
#dir="/; /bin/cat /etc/passwd; /bin/rm -rf /home"


> # 全然解決策になっていなくてすいま
> # せん。

いえいえ、とんでもないです。
いっつもはその方法でやってますので。

ではでは


--
Hideto "rubyholic" ISHIBASHI  http://www.rr.iij4u.or.jp/~hideto-i/