Вы должны испортить привязку, вызвав метод 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
Руби см. Превосходное описание в книге "Кирка" .