From: YAMAGUCHI S. <val...@gm...> - 2006-11-21 17:56:06
|
山口です。 すみません、若干主題が tDiary から離れてしまいましたが。 06/11/21 に Kouhei Sutou<ko...@co...> さんは書きました: > > > 普通はRSS::ListenerMixinに(悪意があるかもしれない)外部から勝手 > > > にメソッドを追加するような使い方はされないと思うので,内部でuntaint > > > しても問題なさそうな気がしますが,今の私には自信を持ってそれをする > > > ことができません.(安全かどうかを判断できないので) > > > > > > RSS Parserのユーザが安心できるなら,untaintしてRSS Parserに渡して > > > やる方がいいのではないかと思うのですが,こちらもそうすべきだ!と > > > までは言えません. > > > > フィードの URL が信頼できるなら、得られるリソースも信頼できると考えて、 > > recent-rss 内で untaint してから RSS Parser に渡すのが妥当だと思えてき > > ました。 > > ごめんなさい. > 要素名の部分だけuntaintするなら,RSS Parser内でuntaintしてもいい > かもと思えてきました.理由は,descriptionなどのコンテンツ部分は > taintされたまま残るからです. > > 要素名の部分に関しては,それらは対応するRSS Parserのオブジェク > トを作るためだけに使って,パース後には残っていない値なので, > まぁ,いいかなぁと思います.いや,でも,そのときにいたずらされ > ちゃうかもしれないのか.うーん,どうしよう. > > 今のままだと結論がだせませんが,もしかしたら,1.8.6の頃には内部 > でuntaintするようになっているかもしれません. ストックで利用される上では大丈夫に思えたのですが、例えば継承やその他の 手段でユーザーにより拡張されて利用される局面を想像すると、やはりライブ ラリ内で untaint するのは避けたほうが良いように感じられました。 ただ、String#intern による SecurityError を救済するのが目的ならば、 untaint を使わなくても可能な事に気づきました。 例えば respond_to? や __send__ ならば、Object#methods からメソッド検索 を行い、得られたクリーンな String の方から Symbol を作成すれば目的を果 たせそうです。 言葉でうまく説明できないので、コードを添付させてもらいます(^^; diff -uNr rss.orig/parser.rb rss/parser.rb --- rss.orig/parser.rb 2006-11-22 02:07:35.000000000 +0900 +++ rss/parser.rb 2006-11-22 02:05:29.000000000 +0900 @@ -311,8 +311,15 @@ prefix, local = split_name(name) @tag_stack.last.push([_ns(ns, prefix), local]) @tag_stack.push([]) - if respond_to?("start_#{local}", true) - __send__("start_#{local}", local, prefix, attrs, ns.dup) + sym = nil + begin + sym = "start_#{local}".intern + rescue SecurityError + found_method = self.methods.find {|m| m == "start_#{local}" } + sym = found_method.intern if found_method + end + if sym and respond_to?(sym, true) + __send__(sym, local, prefix, attrs, ns.dup) else start_else_element(local, prefix, attrs, ns.dup) end diff -uNr rss.orig/rss.rb rss/rss.rb --- rss.orig/rss.rb 2006-11-22 02:07:29.000000000 +0900 +++ rss/rss.rb 2006-11-22 02:02:40.000000000 +0900 @@ -768,7 +768,15 @@ ary = __send__("#{self.class.plural_forms[key]}") ary << next_element else - __send__("#{prefix}#{tag_name}=", next_element) + sym = nil + begin + sym = "#{prefix}#{tag_name}=".intern + rescue SecurityError + found_method = self.methods.find {|m| m == "#{prefix}#{tag_name}=" } + sym = found_method.intern if found_method + end + raise NoMethodError, "undefined method `#{prefix}#{tag_name}=' for #{se lf.inspect}" if sym.nil? + __send__(sym, next_element) end end 他にも対処が必要かもしれないですが、この2箇所へのパッチでひとまずはうま く動いてくれているようです。 # 1.8.5 のこの変更は web アプリケーションの分野ではインパクトが大きそう に思えるのですが、他では話題に上がっていないんでしょうかねえ・・・ -- YAMAGUCHI Seiji <va...@un...> http://underscore.jp |