読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

セーフレベル

Rubyリファレンスマニュアル - セキュリティモデルより。Rubyでは、セーフレベルによりスレッドが実行可能な操作が制限されます。

  • セーフレベル
    • スレッドのセキュリティレベルを示す値。0から4まであり、基本的に数が大きくなるほど制限が増える。
    • スレッドローカル変数として保持される。スレッドごとの値。
    • プログラム開始時のセーフレベルは0
    • スレッド生成時に親スレッドのセーフレベルを引き継ぐ。
    • スレッド内で一度数を増やしたら、引き下げることはできない

例えば、セーフレベル1以上では、汚染されたパスを指定してのファイルへのアクセスが禁止されます。

  • 汚染
    • オブジェクトが安全かどうかを示す属性値。以下の目的で使用されます。
      • 信用できないオブジェクトを入力としてのプログラムの実行を防ぐ
      • 信用できないプログラムから、信頼できるオブジェクトを守る
    • 例えば、ARGVの文字列はデフォルトで汚染されており、セーフレベル1以上環境であれば、それをパス文字列としてファイルにアクセスすることは禁止されます。
    • セーフレベル3以上では、生成されるすべてのオブジェクトが汚染されたりします。
    • 「Object#taint」で汚染したり、「Object#untaint」で汚染を解除したりできます。

以下は、0-3の各セーフレベルでファイルにアクセスしてみるサンプルです。

# ブロックを実行し、SecurityErrorとなるのを確認する関数。
def expects_security_error 
  begin
    yield
    raise "期待と違う"
  rescue SecurityError
  end
end


path = "./foo"               # 汚染されていない文字列 
taint_path = "./taint".taint # 汚染された文字列

#---
# セーフレベル0(デフォルト)
$SAFE = 0

# 特に制限はなし
File.open(path, "w"){|f| f.puts "a" }
File.open(taint_path, "w"){|f| f.puts "a" }


#---
# セーフレベル1
$SAFE = 1

# 汚染されていないファイルへのアクセスは許可される。
File.open(path, "w"){|f| f.puts "a" }

# 汚染された文字列をパスとしてFileを開くとエラー。
# ARGVの値などはデフォルトで汚染されるので、
# ユーザーが入力した安全でないパスへのアクセスを禁止できる。
expects_security_error { 
  File.open(taint_path, "w"){|f| f.puts "a" } 
}


#---
# セーフレベル2
$SAFE = 2

# レベル1と同じく汚染された文字列をパスとしてFileを開くとエラー。
File.open(path, "w"){|f| f.puts "a" }
expects_security_error { 
  File.open(taint_path, "w"){|f| f.puts "a" } 
}

# レベル2になると、mkdirやtrapもできなくなる。
expects_security_error { 
  Dir.mkdir("./foo")
}
expects_security_error { 
  trap(:TERM) { puts "term" }
}


#---
# セーフレベル3
$SAFE = 3

File.open(path, "w"){|f| f.puts "a" }
expects_security_error { 
  File.open(taint_path, "w"){|f| f.puts "a" } 
}
# 生成されるオブジェクトがデフォルトで汚染されるようになる。
expects_security_error { 
  File.open( "./new", "w"){|f| f.puts "a" } 
}


# ちなみに、セーフレベルを下げようとするとエラーになる
expects_security_error { 
  $SAFE = 0
}