J'ai une situation avec un code qui eval()
est apparu comme une solution possible. Maintenant, je n'ai jamais eu à l'utiliser eval()
auparavant, mais j'ai trouvé de nombreuses informations sur le danger potentiel qu'il peut causer. Cela dit, je me méfie beaucoup de son utilisation.
Ma situation est que j'ai une entrée donnée par un utilisateur:
datamap = raw_input('Provide some data here: ')
Où datamap
doit être un dictionnaire. J'ai cherché et j'ai trouvé que cela eval()
pouvait fonctionner. J'ai pensé que je pourrais être en mesure de vérifier le type d'entrée avant d'essayer d'utiliser les données et ce serait une précaution de sécurité viable.
datamap = eval(raw_input('Provide some data here: ')
if not isinstance(datamap, dict):
return
J'ai lu les documents et je ne sais toujours pas si cela serait sûr ou non. Eval évalue-t-il les données dès leur saisie ou après l' datamap
appel de la variable?
Le ast
module est-il .literal_eval()
la seule option sûre?
ast.literal_eval("1 & 1")
lancera une erreur maiseval("1 & 1")
ne le fera pas.ast.literal_eval
pour quelque chose comme ça (par exemple, vous pourriez implémenter un analyseur manuellement).ast.literal_eval()
considère qu'un petit sous-ensemble de la syntaxe de Python est valide:Passer
__import__('os').system('rm -rf /a-path-you-really-care-about')
àast.literal_eval()
entraînera une erreur, maiseval()
effacera volontiers votre lecteur.Comme il semble que vous ne laissez l'utilisateur entrer qu'un dictionnaire simple, utilisez
ast.literal_eval()
. Il fait en toute sécurité ce que vous voulez et rien de plus.la source
eval: Ceci est très puissant, mais est également très dangereux si vous acceptez des chaînes à évaluer à partir d'une entrée non approuvée. Supposons que la chaîne évaluée soit "os.system ('rm -rf /')"? Il commencera vraiment à supprimer tous les fichiers de votre ordinateur.
ast.literal_eval: évalue en toute sécurité un nœud d'expression ou une chaîne contenant un littéral Python ou un affichage de conteneur. La chaîne ou le nœud fourni ne peut être constitué que des structures littérales Python suivantes: chaînes, octets, nombres, tuples, listes, dictées, ensembles, booléens, Aucun, octets et ensembles.
Syntaxe:
Exemple:
Dans le code ci-dessus,
().__class__.__bases__[0]
rien d'autre que l'objet lui-même. Maintenant que nous avons instancié toutes les sous - classes , ici notreenter code here
objectif principal est de trouver une classe nommée n à partir de celle-ci.Nous avons besoin d'
code
objecter et d'function
objecter à partir de sous-classes instanciées. Il s'agit d'une autre manière d'CPython
accéder aux sous-classes d'objets et d'attacher le système.Depuis python 3.7, ast.literal_eval () est désormais plus stricte. L'addition et la soustraction de nombres arbitraires ne sont plus autorisées. lien
la source
ast.literal_eval("1+1")
ne fonctionne pas en python 3.7 et comme dit précédemment, literal_eval devrait être limité aux littéraux de ces quelques structures de données. Il ne devrait pas pouvoir analyser une opération binaire.KABOOM
code, s'il vous plaît?KABOOM
KABOOM
est bien expliqué ici: nedbatchelder.com/blog/201206/eval_really_is_dangerous.htmlPython est impatient de
eval(raw_input(...))
procéder à son évaluation, il évaluera donc l'entrée de l'utilisateur dès qu'elle atteindra leeval
, indépendamment de ce que vous faites des données par la suite. Par conséquent, ce n'est pas sûr , en particulier lorsque vouseval
entrez par l'utilisateur.Utilisez
ast.literal_eval
.À titre d'exemple, entrer ceci à l'invite sera très, très mauvais pour vous:
la source
Si tout ce dont vous avez besoin est un dictionnaire fourni par l'utilisateur, une meilleure solution est possible
json.loads
. La principale limitation est que json dicts nécessite des clés de chaîne. De plus, vous ne pouvez fournir que des données littérales, mais c'est également le casliteral_eval
.la source
J'étais coincé avec
ast.literal_eval()
. Je l'ai essayé dans le débogueur IntelliJ IDEA, et il a continué à revenirNone
sur la sortie du débogueur.Mais plus tard, quand j'ai assigné sa sortie à une variable et l'ai imprimée dans le code. Cela a bien fonctionné. Exemple de code de partage:
Sa version python 3.6.
la source