Как пометить Ruby Binding как доверенный? - PullRequest
5 голосов
/ 01 сентября 2010

Из этой статьи http://www.stuartellis.eu/articles/erb в отношении уровней безопасности потока:

"На этом уровне указанная привязка должна быть помечена как доверенная для ERB, чтобы использовать ее."

Я искал все выше и ниже и не нашел способа «пометить» привязку как «доверенную».

Кто-нибудь, пожалуйста, просветите меня?

1 Ответ

9 голосов
/ 02 сентября 2010

Вы должны испортить привязку, вызвав метод taint.

Уровни $SAFE - это особенность Ruby, которая запрещает определенные действия в зависимости от текущего уровня и того, является ли объект испорченным . Предполагается, что испорченные строки происходят из ненадежного источника, такого как файл, база данных, HTTP-клиент и т. Д.

Например, на уровне $SAFE уровня 1 Ruby не разрешит вам require файлы, если аргумент является испорченной строкой.

$SAFE уровень 4 самый экстремальный. Ruby эффективно запретит вам модифицировать любой неохраняемый объект. Идея заключается в том, что вы можете использовать более низкий уровень $SAFE в своем приложении и создать поток или процесс с $SAFE уровнем 4. В этой песочнице вы можете изменить tainted только объекты.

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

Блам! Это Руби, которая говорит вам, что нехорошо модифицировать объект без 10 * * на $SAFE уровне 4. Это не позволит вам вызвать eval с данное связывание (именно это и пытается ERB).

Вместо этого вы должны предоставить песочнице привязку tainted . Вы явно указываете 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!"

Для получения дополнительной информации об уровне $SAFE Руби см. Превосходное описание в книге "Кирка" .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...