web-dev-qa-db-fra.com

Python: sécuriser eval

Je veux un moyen facile de faire une "API de calculatrice" en Python.

En ce moment, je ne me soucie pas beaucoup de l'ensemble exact de fonctionnalités que la calculatrice va prendre en charge.

Je veux qu'il reçoive une chaîne, dites "1+1" et retourner une chaîne avec le résultat, dans notre cas "2".

Existe-t-il un moyen de rendre eval sans danger pour une telle chose?

Pour commencer je ferais

env = {}
env["locals"]   = None
env["globals"]  = None
env["__name__"] = None
env["__file__"] = None
env["__builtins__"] = None

eval(users_str, env)

afin que l'appelant ne puisse pas jouer avec mes variables locales (ou les voir).

Mais je suis sûr que je supervise beaucoup ici.

Les problèmes de sécurité de eval peuvent-ils être corrigés ou y a-t-il simplement trop de petits détails pour le faire fonctionner correctement?

40
flybywire

les problèmes de sécurité d'eval peuvent-ils être résolus ou y a-t-il simplement trop de petits détails pour le faire fonctionner correctement?

Certainement ce dernier - un pirate intelligent parviendra toujours à trouver un moyen de contourner vos précautions.

Si vous êtes satisfait d'expressions simples utilisant uniquement des littéraux de type élémentaire, utilisez ast.literal_eval - c'est pour ça! Pour tout ce qui est plus sophistiqué, je recommande un paquet d'analyse, comme ply si vous êtes familier et à l'aise avec l'approche classique lexx/yacc, ou pyparsing pour une approche peut-être plus pythonique .

58
Alex Martelli

Il est possible d'accéder à n'importe quelle classe qui a été définie dans le processus, puis vous pouvez l'instancier et invoquer des méthodes dessus. Il est possible de segfault l'interpréteur CPython, ou de le faire quitter. Voir ceci: Eval est vraiment dangereux

12
Ned Batchelder

Les problèmes de sécurité ne sont pas (même proches) réparables.

J'utiliserais pyparsing pour analyser l'expression dans une liste de jetons (cela ne devrait pas être trop difficile, car la grammaire est simple), puis gérer les jetons individuellement.

Vous pouvez également utiliser le module ast pour créer une Python AST (puisque vous utilisez une syntaxe Python valide _ ), mais cela peut être ouvert à de subtiles failles de sécurité.

1
Katriel

Perl a un module Safe eval http://perldoc.Perl.org/Safe.html

La recherche sur "l'équivalent Python de Perl Safe" recherche http://docs.python.org/2/library/rexec.html

mais ce Python "exec restreint" est déconseillé.

-

dans l'ensemble, la sécurité "eval", dans toutes les langues, est un gros problème. Les attaques par injection SQL ne sont qu'un exemple d'un tel trou de sécurité. Perl Safe a connu des bugs de sécurité au fil des ans - le plus récent dont je me souvienne, il était sûr, à l'exception des destructeurs sur les objets renvoyés par l'évaluation sécurisée.

C'est le genre de chose que je pourrais utiliser pour mes propres outils, mais pas exposé sur le Web.

Cependant, j'espère qu'un jour des versions entièrement sécurisées seront disponibles dans de nombreuses/toutes les langues.

1
Krazy Glew