J'ai été chargé de construire une application dans laquelle un utilisateur final peut avoir des règles personnalisées pour évaluer si une requête retournée entraîne un avertissement ou une alerte (basé sur de nombreux seuils).
J'ai construit un moyen pour le utilisateur de modeler leur logique. Un exemple ressemble à ceci: p> le Ceci sera Mon code se termine par regarder comme ceci: p> Cependant, l'exécutif échoue lorsque j'ai le deuxième et troisième paramètre avec cette exception - Une partie de la logique personnalisée Les utilisateurs finaux ont été étendus et une grande partie de ces changements sur une base assez régulière. Je ne veux pas maintenir leur logique personnalisée et que les utilisateurs finaux veulent pouvoir tester rapidement diverses logiques de seuil d'avertissement / d'alerte. p> Comment puis-je sécuriser cette instruction Exec d'un code dangereux (intentionnel ou non)? P> P> << 21 >> code> et << 22 >> code> les paramètres seront substitué avec des valeurs trouvées plus tôt dans le programme. Une fois que toute cette substitution se produit, j'ai un bloc très simple si / sinon (dans cet exemple) qui ressemble à ceci enregistré dans une variable ( EXECCD code>): p> EXEC () code> correctement. Maintenant, comment puis-je sécuriser cela? J'ai examiné cet article: http://lybniz2.sourceforge.net/safeeval.html P> NomError: Nom 'Rettval' n'est pas défini Code> P>
3 Réponses :
Le seul moyen sûr d'utiliser Vous n'avez pas besoin d'utiliser EXEC. Au lieu de construire une chaîne à exécuter, analysez-la dans des objets et utilisez-le pour piloter votre exécution de code. P>
À sa plus simple, vous pouvez stocker des fonctions dans une dict et utiliser une chaîne pour sélectionner la fonction à appeler. Si vous utilisez la syntaxe Python, Python fournit tous les utilitaires à analyser et à utiliser ceux-ci. P> eval code> ou exec code> ne doit pas les utiliser. p>
Pouvez-vous s'il vous plaît inclure quels utils vous parlez ici?
Bien que cela soit d'environ 8 ans, je répondrai toujours. Je crois que le module ast code> est ce dont ils parlent.
Pouvez-vous fournir un exemple de comment éviter d'utiliser EXED?
Votre relevé EXEC code> n'ajoute pas de retval à votre environnement local, mais au dictionnaire Safe_Dict CODE>. Donc, vous pouvez le récupérer de là: execCd = """
if (abs(22.0) >= abs(-162.0)):
retVal = 22.0
else:
retVal = -162.0
"""
safe_list = ['math','acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'de grees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
safe_dict['abs'] = abs
exec(execCd,{"__builtins__":None},safe_dict)
retVal = safe_dict["retVal"]
Voici comment je le vois de l'expérience que j'avais - il y a deux dangers principaux avec EXED et EVAL, dans lequel je veux dire, il y a une solution de contournement pour les deux:
Tout d'abord, vous avez un code source exécuté dans un code source. Cela signifie que ce code: p> donnera à l'utilisateur l'accès à toutes les variables et toutes les instances de l'ensemble du module. Nous ne voulons pas cela. S'il s'agissait d'un serveur de flacon connecté à MySQL faire une évaluation de cette façon, c'est comme ouvrir une porte au public pour voir vos mots de passe. Cet utilisateur vient de recevoir votre mot de passe MySQL et géré pour ne pas simplement vous connecter, mais également pour effacer toutes les données et modifier le mot de passe. Félicitations! P> Au lieu de cela, vous devrez créer un dictionnaire où vous donnez uniquement les utilisateurs uniquement les variables essentielles. Si vous ne le souhaitez pas, vous pouvez également insérer un dictionnaire vide. P> eval("open('wpadmin/sql.ini').read()",scope,scope) # this will now failed since we defined "open" as None in the scope.
Err ... Stackoverflow.com/questions/3688708/python-safe-sandbox (je peux copier et Coller correctement, vraiment)