Comment voulez-vous marquer un binding Ruby comme digne de confiance?
-
26-09-2019 - |
Question
A partir de cet article http://www.stuartellis.eu/articles/erb se référant à les niveaux de sécurité de filetage:
« A ce niveau, la liaison spécifiée doit être marqué comme fiable pour ERB l'utiliser. »
J'ai cherché haut et bas et n'ont pas trouvé un moyen de « marquer » une liaison comme « de confiance ».
Quelqu'un va me s'il vous plaît éclairer?
La solution
Vous devez entacher la liaison en appelant la méthode taint
.
Les niveaux de $SAFE
sont une caractéristique de Ruby qui refuse certaines actions en fonction du niveau actuel et si un objet est contaminé . cordes souillées sont supposées provenir d'une source non fiable, par exemple un fichier, une base de données, un client HTTP, etc.
Au niveau $SAFE
1, par exemple, Ruby ne vous permettra pas de fichiers require
si l'argument est une chaîne viciée.
niveau $SAFE
4 est la plus extrême. Ruby vous désavouer efficacement à modifier tout nontained objet . L'idée est que vous pouvez utiliser un niveau de $SAFE
inférieur dans votre application, et instancier un fil ou proc avec le niveau de $SAFE
4. Dans ce bac à sable , vous pouvez modifier entachées d'objets uniquement .
ERB utilise ce mécanisme pour vous permettre d'exécuter un modèle dans un bac à sable. Si vous essayez d'obtenir le résultat d'un modèle rendu à partir d'un certain liant, voici ce qui se passe:
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
Blam! Ce Ruby vous dire qu'il est pas correct de modifier un nontainted objet au niveau de $SAFE
4. Il ne vous permettra pas d'appeler eval
avec la donnée contraignant (ce qui est exactement ce que les tentatives ERB).
Au lieu de cela, vous devez fournir le bac à sable avec un contaminé contraignant. Vous dites explicitement Ruby qu'il est acceptable d'utiliser cette liaison dans un bac à sable, et qu'il ne devrait pas faire confiance à l'extérieur du bac à sable.
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!"
Pour plus d'informations sur le niveau de $SAFE
Ruby, consultez le excellente description dans le livre Pioche.