Question

Si j'évalue une chaîne Python à l'aide de eval () et que ma classe est la suivante:

class Foo(object):
    a = 3
    def bar(self, x): return x + a

Quels sont les risques de sécurité si je ne fais pas confiance à la chaîne? En particulier:

  1. Est-ce que eval(string, {"f": Foo()}, {}) est dangereux? C’est-à-dire, pouvez-vous atteindre os ou sys ou quelque chose de non sûr à partir d’une instance de Foo?
  2. Est-ce que eval(string, {}, {}) est dangereux? C’est-à-dire, puis-je accéder à os ou à un système entièrement à partir de fonctions intégrées telles que len et list?
  3. Existe-t-il un moyen de rendre les éléments intégrés totalement absents du contexte eval?

Il existe des chaînes peu sûres comme & "; [0] * 100000000 &"; Je m'en fiche, car au pire ils ralentissent / arrêtent le programme. Je tiens avant tout à protéger les données des utilisateurs externes au programme.

Évidemment, eval(string) sans dictionnaires personnalisés est dangereux dans la plupart des cas.

Était-ce utile?

La solution

Vous ne pouvez pas sécuriser eval avec une telle approche de liste noire. Voir Eval est vraiment dangereux pour obtenir des exemples d'entrées qui vont se transformer en erreur par l'interpréteur CPython, donner accès à toute classe que vous aimez, et ainsi de suite.

Autres conseils

eval() permettra à des données malveillantes de compromettre l'intégralité de votre système, de tuer votre chat, de manger votre chien et de faire l'amour à votre femme.

Il y avait récemment un fil de discussion sur la façon de faire ce genre de chose en toute sécurité sur la liste python-dev, et les conclusions étaient les suivantes:

  • C'est vraiment difficile de le faire correctement.
  • Des correctifs à l'interpréteur python sont nécessaires pour bloquer de nombreuses classes d'attaques.
  • Ne le faites pas si vous ne le voulez pas vraiment.

Commencez ici pour en savoir plus sur le défi: http: // tav.espians.com/a-challenge-to-break-python-security.html

Dans quelle situation voulez-vous utiliser eval ()? Voulez-vous qu'un utilisateur puisse exécuter des expressions arbitraires? Ou souhaitez-vous transférer des données d'une manière ou d'une autre? Peut-être qu'il est possible de verrouiller l'entrée d'une certaine manière.

Vous pouvez accéder à os à l'aide des fonctions intégrées: __import__('os').

Pour Python 2.6+, le module ast peut aider; en particulier ast.literal_eval, bien que cela dépende exactement de ce que vous voulez évaluer.

Notez que même si vous transmettez des dictionnaires vides à eval (), il est toujours possible de segfault (C) Python avec quelques astuces de syntaxe. Par exemple, essayez ceci sur votre interprète: eval("()"*8**5)

Vous feriez probablement mieux de tourner la question:

  1. Quel type d'expressions souhaitez-vous évaluer?
  2. Pouvez-vous vous assurer que seules les chaînes correspondant à une syntaxe définie de manière étroite sont eval () d?
  3. Ensuite, considérez si que est en sécurité.

Par exemple, si vous souhaitez laisser l’utilisateur saisir une expression algébrique à des fins d’évaluation, envisagez de les limiter à une lettre, aux noms de variable, aux nombres et à un ensemble spécifique d’opérateurs et de fonctions. N'évaluez pas les chaînes contenant des éléments.

Il existe un très bon article sur la non-sécurité de eval() Plongez dans Python de Mark Pilgrim.

Cités dans cet article:

  

En fin de compte, il est possible de   évaluer des expressions Python non fiables,   pour une définition de & # 8220; safe & # 8221; cette   se révèle ne pas être très utile dans   vrai vie. C'est & # 8217; ça va si vous & # 8217; soyez juste   jouer, et & # 8217; va bien si vous   seulement jamais passer cette entrée de confiance. Mais   tout le reste demande juste   problème.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top