2010-01-03 6 views
3

Je construis un site web où j'ai besoin que l'utilisateur puisse évaluer une expression basée sur la valeur dans les tables de DB, au lieu d'utiliser des outils comme pyparsing etc, je pense à utiliser python lui-même, et ai trouvé une solution qui est suffisante pour mon but. J'utilise eval pour évaluer l'expression et passer des globaux à vide avec __builtins__ afin que rien ne soit accessible et qu'un local dicte des valeurs de DB, si l'utilisateur aura besoin de certaines fonctions. Je peux les passer par exemple.Quelle est la sécurité de l'évaluation d'expression en utilisant eval?

import datetime 
def today(): 
    return datetime.datetime.now() 

expression = """ first_name.lower() == "anurag" and today().year == 2010 """ 

print eval(expression, {'__builtins__':{}}, {'first_name':'Anurag', 'today':today}) 

Alors ma question est de savoir comment il serait en sécurité, j'ai trois critères

  1. peut accéder à l'utilisateur l'état actuel de mon programme ou d'une table etc someshow?
  2. L'utilisateur peut-il accéder aux appels de niveau os?
  3. L'utilisateur peut-il arrêter mon système en faisant une boucle ou en utilisant beaucoup de mémoire, par ex. en faisant la gamme (10 * 8), dans certains cas, il peut par exemple 100 ** 1000 etc, donc 3 n'est pas tellement un problème. Je peux vérifier cette opération avec tokenize et de toute façon je vais utiliser GAE donc ce n'est pas très préoccupant.

Modifier: l'OMI ce n'est pas le double de Q:661084 car où elle se termine celui-ci commence, je veux savoir, même avec __builtins__ bloqué, peut faire de mauvaises choses utilisateur?

+0

Vérifiez: http: // stackoverflow.com/questions/661084/security-of-pythons-eval-on-unstrusted-cordes – fserb

+0

@fserb voir edit –

Répondre

7

Il est tout à fait dangereux d'utiliser eval, même avec Encastrements vidées et bloquées - l'attaquant peut commencer par un littéral, obtenir son __class__, etc, etc, jusqu'à object, son __subclasses__, et ainsi de suite ... Fondamentalement, l'introspection de Python est trop forte pour résister à un attaquant expérimenté et déterminé.

ast.literal_evalest sûr, si vous pouvez vivre ses limites ...

+1

ok je vous crois :) mais un contre-exemple serait amusant, de toute façon je vais essayer PyParsing alors. –

+1

L'indication que vous pouvez obtenir à * any * type ou class (en passant à 'object', par exemple' __class__' et '__mro__' ou' __bases__', puis en passant par '__subclasses__', ...) devrait suffire comme "contre-exemple": laissez les pirates informatiques malveillants qui veulent jouer des tours destructeurs au moins travailler une minute pour construire leurs solutions ...! -) –

4

Certes, il est possible de consommer toute la mémoire disponible ou de créer une boucle infinie même sans les builtins. Il y a plusieurs façons de le faire comme « un » * 999999 * 999999 ou pour faire une boucle infinie:

>>> print eval('[[x.append(a) for a in x] for x in [[0]]]', 
...    {'__builtins__':{}}, {'first_name':'Anurag', 'today':today}) 

En ce qui concerne 1) et 2), je ne suis pas sûr, mais il semble risqué. Voici une chose que j'ai essayé que je pensais que cela fonctionnerait, mais il semble que quelqu'un d'autre déjà considéré que la ligne d'attaque et a bloqué:

>>> import datetime 
>>> def today(): 
>>>  return datetime.datetime.now() 
>>> 
>>> print eval('today.func_globals', {'__builtins__':{}}, {'first_name':'Anurag', 'today':today}) 
RuntimeError: restricted attribute 

je moitié attendais à avoir ce lieu:

{'__builtins__': <module '__builtin__' (built-in)>, ... 

Donc, je pense que c'est probablement une mauvaise idée. Vous n'avez besoin que d'un petit trou et vous donnez accès à tout votre système. Avez-vous envisagé d'autres méthodes qui n'utilisent pas eval? Qu'est ce qui ne va pas chez eux?

+0

oui réglage __builtins__ variable, le mode d'exécution restreint entre en jeu :) –

+0

+1 pour 'attribut restreint' Je ne savais pas ça, on dirait que c'est dû au vieux module reexec, je voulais utiliser eval car si je peux pourquoi pas? –

2

Il est possible de créer et de se prévaloir d'un quelconque classe définie dans le programme, qui comprend ceux qui peuvent quitter l'interpréteur Python. En outre, vous pouvez créer et exécuter des chaînes arbitraires de bytecode, qui peuvent segfault l'interpréteur. Voir Eval really is dangerous pour tous les détails.

Questions connexes