RubyにはCGI等のプログラミングを安全に行うことを助ける為に、セキュリティ 機構が備わっています。
Rubyのセキュリティモデルは「オブジェクトの汚染」と「セーフレベル」という 仕組みによってなりたっています。
Rubyではオブジェクトは「汚染されている」とみなされることがあります。この しくみは大きく分けて二つの使われ方をします。
ひとつ目は、信用できない入力をもとに作られたオブジェクトを「汚染されてい る」とみなし、「危険な操作」の引数として使えないようにすることです。悪意 あるデータによって、プログラムが意図しない動作をする事を防ぐことを目的と しています。
もうひとつは、信用しているオブジェクト(汚染されていないオブジェクト)を 信用できないプログラムから守るという使い方です。セーフレベル4で汚染されて いないオブジェクトへの操作が大幅に制限されるのはこの事を意図しています。
オブジェクトの汚染に関連するメソッド
オブジェクトを汚染する
オブジェクトが汚染されている場合に真を返す
オブジェクトの汚染を取り除く
各スレッドは固有の「セーフレベル」を持っています。セーフレベルが高くなるほ ど、行える操作は制限されます。セーフレベルはスレッドローカル変数$SAFEで 設定します。
$SAFEに関するルール
原則として、各セキュリティレベルにはそれ以下のセキュリティレベルの制限も 適用されます。たとえばレベル1で許されない操作はレベル2でも行えません。
デフォルトのセーフレベルです。
IOや環境変数、コマンドライン引数(ARGV)から得られた文字列
(環境変数PATHだけは特別)
環境変数PATHだけは例外で、値に危険なパスを含む場合のみ汚染されます。
ここでは危険なパスとは誰でも変更/書き込みが可能なパスをいいます。 ルートディレクトリから階層が順番にチェックされ、一箇所でも誰でも 変更可能な個所があればそのパスは危険とみなされます。
信用しているプログラムで信用できないデータを処理する為のレベルです。 CGI等でユーザからの入力を処理するのに適しています。
レベル1の制限に加え、以下の操作が禁止されます。
生成される全てのオブジェクトが汚染されます。レベル4でプログラムを実行す る環境を作り上げるのに適しています。
レベル2の制限に加え、以下の操作が禁止されます。
信用することのできないプログラムを実行するためのレベルです。
このレベルではレベル3では禁止されている「汚染された文字列のeval」が許可 されています。(evalで実行すると危険な操作は全て禁止されているからです。)
レベル3の制限(上記のとおりevalは除く)に加え、以下の操作が禁止されます。
一端高くした$SAFEレベルを低く変更する事はできませんが、以下のようにスレッ ドを使うことで、プログラムの一部だけを高いセーフレベルで実行することが可 能です。
例:
def safe(level) result = nil Thread.start { $SAFE = level result = yield }.join result end safe(4) { puts "hello" } # $SAFEなので例外 puts "world" # 外側は影響を受けない
*1小宮 : このレベルの特徴は?
*2 dellin: 2001/12/10追記 - Thu May 31 18:34:57 2001のCVS更新分より
*3小宮 : eval.c:5306近辺のつもり。あってます?。