5

この記事http://www.stuartellis.eu/articles/erbから、スレッドセーフレベルについて言及しています。

「このレベルでは、指定されたバインディングは、ERBがそれを使用するために信頼できるものとしてマークする必要があります。」

高低を検索しましたが、バインディングを「信頼できる」と「マーク」する方法が見つかりませんでした。

誰かが私を教えてくれませんか?

4

1 に答える 1

9

メソッドを呼び出してバインディングを汚染する必要がありtaintます。

レベルは、現在の$SAFEレベルとオブジェクトが汚染されているかどうかに応じて特定のアクションを拒否するRubyの機能です。汚染された文字列は、ファイル、データベース、HTTPクライアントなどの信頼できないソースから発信されたものと見なされます。

$SAFEたとえば、レベル1では、引数が汚染された文字列である場合、Rubyはファイルを許可しませんrequire

$SAFEレベル4が最も極端です。Rubyは、汚染されていないオブジェクトの変更を事実上禁止します。$SAFEアプリケーションで下位レベルを使用し、レベル4でスレッドまたはプロシージャをインスタンス化できるという考え方です$SAFE。このサンドボックス内では、汚染されたオブジェクトのみを変更できます。

ERBはこのメカニズムを使用して、サンドボックス内でテンプレートを実行できるようにします。特定のバインディングからレンダリングされたテンプレートの結果を取得しようとすると、次のようになります。

class TemplateContext
  def name; "Teflon Ted"; end
end

template_binding = TemplateContext.new.send(:binding)
ERB.new("Hi, <%= name %>!", 4).result(template_binding)

#=> SecurityError: Insecure: can't modify trusted binding

ブラム!これはRubyであり、レベル4で汚染されていないオブジェクトを変更することはできません。指定されたバインディングで呼び出すことはできません(これはまさにERBが試みることです)。$SAFEeval

代わりに、サンドボックスに汚染されたバインディングを提供する必要があります。このバインディングをサンドボックスで使用しても問題がないこと、およびサンドボックスの外部で信頼されるべきではないことをRubyに明示的に伝えています。

class TemplateContext
  def name; "Teflon Ted"; end
end

# Binding must be tainted!
template_binding = TemplateContext.new.send(:binding).taint
ERB.new("Hi, <%= name %>!", 4).result(template_binding)

#=> "Hi, Teflon Ted!"

Rubyの$SAFEレベルの詳細については、Pickaxeの本の優れた説明を参照してください。

于 2010-09-02T11:50:02.990 に答える