Como você marca uma ligação do rubi como confiável?
-
26-09-2019 - |
Pergunta
A partir deste artigo http://www.stuartellis.eu/articles/erb Referindo -se aos níveis de segurança de threads:
"Nesse nível, a ligação especificada deve ser marcada como confiável para o ERB usá -lo".
Eu procurei alto e baixo e não encontrei uma maneira de "marcar" uma ligação como "confiável".
Alguém vai me esclarecer?
Solução
Você deve Taint a ligação chamando o taint
método.
o $SAFE
Os níveis são uma característica do rubi que nega certas ações, dependendo do nível atual e se um objeto é contaminado. Supõe -se que as cordas contaminadas se originem de uma fonte não confiável, como um arquivo, um banco de dados, um cliente HTTP, etc.
No $SAFE
Nível 1, por exemplo, Ruby não permitirá que você require
arquivos se o argumento for uma string contaminada.
$SAFE
O nível 4 é o mais extremo. Ruby irá efetivamente desaprová -lo para modificar qualquer não objeto. A idéia é que você possa usar um menor $SAFE
nível em seu aplicativo, e instanciar um tópico ou proc com $SAFE
Nível 4. Dentro disso caixa de areia, você pode modificar contaminado apenas objetos.
O ERB usa esse mecanismo para permitir que você execute um modelo dentro de uma caixa de areia. Se você tentar obter o resultado de um modelo renderizado de uma certa ligação, é isso que acontece:
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
Culpa! Este é Ruby dizendo que é Não é bom modificar um não pintado objeto em $SAFE
Nível 4. Não permitirá que você ligue eval
com a ligação dada (que é exatamente o que o ERB tenta).
Em vez disso, você deve fornecer à caixa de areia um contaminado vinculativo. Você está dizendo explicitamente a Ruby que não há problema em usar essa ligação em uma caixa de areia e que ela não deve ser confiável fora da caixa de areia.
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!"
Para mais informações sobre o Ruby's $SAFE
nível, veja o Excelente descrição no livro de picareta.