まつもと ゆきひろです

In message "[ruby-list:19304] about -T option on ruby 1.4.2"
    on 99/12/09, nakajima kengo <ringo / hompo.co.jp> writes:

|ruby 1.4.2 における、セキュリティチェック機能について、
|質問させてください。
|  ふと、誰でもがrubyで遊べるWebページを作ろうと思いたって
|
|http://eco.hompo.co.jp/~ringo/hack/rubyonline/ruby.cgi?code=print%20%22Hello%20World%22
|
|みたいなページ(CGI)を作ってみたのですが、そのページの
|安全性を知りたいのです。
|  CGIの中身を単純に説明すれば、ユーザーからスクリプトを
|受けとってサーバーでrubyインタプリタに渡すだけの単純なものです。

うーん、任意のRubyコードを実行できるCGIなんですね。危険だ。

|もちろんそんなことをすればセキュリティ的に大問題なので、
|ruby -T3 しています。-T4にしないのは、標準出力に出力させ
|たいからです。

自分で作っといてなんですが、-T3 はあまり意味のあるレベルでは
ないです。-T1 が「普通の」CGI用、-T2,-T3 は飾り(あんまりだ)
で、-T4が任意のRubyコードを安全に実行できる(ようにしたい)と
いうレベルです。

標準出力に出力させたいと言うことですが、それも十分に危険なの
で、安全のためには以下の手順が良いのではないかと思います。

  * 全体は-T1
  * ユーザからのリクエストをファイルに書き出す
  * $>を適切に設定する
  * 新しいスレッドを起動
  * スレッド内で $SAFE=4
  * スレッド内で loadの第2引数をtrueにしてユーザリクエストを
    ロード

以下のような感じかなあ(試してません)。

  require 'thread'
  user_program = CGI["script"].join

  path = "/tmp/script#{$$}"
  f = open(path, "w")
  f.print user_program
  f.close

  Thread.current["defout"] = $>
  queue = Queue.new
  def <<queue
    alias write push
  end
  Thread.start do
    defout = $>
    loop do
      defout.write queue.pop
    end
  end

  $> = Object.new
  class << $>
    def write(str)
       Thread.current["defout"].write(str)
    end
  end

  Thread.start do
    Thread.current["defout"] = queue
    $SAFE=4
    load(path, true)
  end
  File.unlink(path)

なんか複雑ですね。ライブラリを作った方が良さそうだなあ。

|もちろん、根本的に危険なことはするな、と言われそうですが、
|それでも、なぜ危険なのか、を知りたいのです。

つまり、-T3レベルでの危険性についてですね。-T3では入出力が禁
止されませんから、

  * 情報の漏洩

が考えられます。nobodyが読みだせる範囲内のホスト上のファイル
の内容などを読み出されてしまう可能性があるわけですね。-T3で
はuntaintが使えますから、プログラムを解放してしまうと汚染モ
デルによる防御は無効です。

うーん、-T3でuntaintを禁止すれば良いのかな、ちょっと考えてみ
よう。いずれにせよ、セキュリティモデルは完全性が保証されてい
ませんから、いくばくかの冒険になります。が、私としては経験を
積みたい分野なのでチャレンジは大歓迎です。

                                まつもと ゆきひろ /:|)