À l'époque où j'implémentais le moteur JScript, je préconisais d' imprimer les chemises EVAL IS EVIL , mais malheureusement, nous n'y sommes jamais parvenus.
Mon plus gros problème avec eval n'est pas l'attaque évidente par injection de code malveillant, bien que cela soit certainement extrêmement préoccupant. Mon plus gros problème est que les gens ont tendance à l'utiliser comme un très gros marteau pour résoudre de très petits problèmes. La plupart des utilisations réelles de «eval» dans la nature lorsque je faisais partie de l'équipe JScript auraient pu être résolues de manière triviale en utilisant une table de recherche; et comme chaque objet dans JScript est déjà une table de recherche, ce n'est pas comme si c'était une lourde charge. Eval redémarre le compilateur et détruit complètement la capacité du compilateur à optimiser votre code .
Pour plus de réflexions dans ce sens, voir mes articles de 2003 sur le sujet:
Malfaisance générale:
http://blogs.msdn.com/b/ericlippert/archive/2003/11/01/53329.aspx
Injection attaque le mal:
http://blogs.msdn.com/b/ericlippert/archive/2003/11/04/53335.aspx
eval
pensez-vous de l'utilisation de gros morceaux de code comme le font des applications comme JSPacker? JSPacker + gzip entraîne généralement des tailles de fichier plus petites que les deux solutions en soi, mais comme vous le faites remarquer à juste titre, il lance essentiellement un compilateur deux fois sur le même morceau de code, plus une surcharge pour effectuer des remplacements de chaîne.eval()
est pas un risque de sécurité sur le code client (navigateur).La plupart des trous de sécurité sont le même type de trous qu'avec l'injection SQL, à savoir la concaténation des entrées utilisateur dans le code JavaScript. La différence étant que bien qu'il existe des moyens de garantir que cela ne se produise pas avec SQL, il n'y a pas grand-chose que vous puissiez faire avec JavaScript.
À titre d'exemple trivial et inutile, une calculatrice JavaScript simpliste:
Quelques exemples d'utilisation corrects sont certains des compresseurs JavaScript qui compressent JavaScript en extrayant les mots courants et en les remplaçant par de courts remplacements de 1 à 2 caractères. L'emballeur sort ensuite tout cela avec un code de remplacement de chaîne basé sur le dictionnaire généré puis évalue le résultat.
la source
Il y a des choses qui sont impossibles à faire dans JS sans fonction comme eval (
eval
,Function
et peut - être plus).Prenez
apply
par exemple. Il est facile à utiliser lors de son utilisation sur des appels de fonction ordinaires:foo.apply(null, [a, b, c])
Mais comment feriez-vous cela pour les objets que vous créez via une nouvelle syntaxe?
new Foo.apply(null, [a, b, c])
ne fonctionne pas, pas plus que les formulaires similaires.Mais vous pouvez contourner cette limitation via
eval
ouFunction
(j'utiliseFunction
dans cet exemple):Exemple:
Foo.New.apply(null, [a, b, c])
;Bien sûr, vous pouvez créer manuellement les fonctions qui
Function.prototype.New
utilisent, mais non seulement c'est verbeux et maladroit, mais (par définition) il doit être fini.Function
permet au code de fonctionner pour n'importe quel nombre d'arguments.la source
eval()
non " Quelle est la bonne utilisation de ? "Une réponse quelque peu directe de ma part a été de développer une zone de test API orientée développeur. Nous avons donné une zone de texte sur une page et un bouton Exécuter. Le point central de la page était pour eux de pouvoir essayer des choses en Javascript contre notre API communicante iframe qui n'était pas si facile à faire dans un environnement local.
Tout ce qui aurait pu être malveillant dans ce cas aurait également pu être fait par le développeur ouvrant ses outils F12.
la source
Je suis d'accord qu'il devrait très rarement être utilisé, mais j'ai trouvé un cas d'utilisation puissant pour
eval
.Il y a une nouvelle fonctionnalité expérimentale dans Firefox appelée asm.js avec laquelle je travaille. Il permet de compiler un sous-ensemble limité du langage Javascript en code natif. Oui, c'est très génial, mais cela a des limites. Vous pouvez considérer le sous-ensemble limité de Javascript comme un langage de type C intégré à Javascript. Il n'est pas vraiment destiné à être lu ou écrit par des humains.
Ce sous-ensemble limité de Javascript ne me permet pas d'injecter mon code généré lors de l'exécution dans le code compilé une fois qu'il a été compilé.
J'ai écrit du code qui permet à un utilisateur d'écrire, en notation familière, une expression mathématique, et de la convertir à la volée en code asm.js. À moins que je veuille faire traiter le code côté serveur (ce que je ne fais pas),
eval
c'est le seul outil qui me permet de faire traiter le code résultant par le navigateur en temps réel.la source
Comme l'ont souligné d'autres, la chose la plus importante lorsque vous travaillez avec
eval
est de la garder en sécurité. Pour cela, vous voulez faire une vérification approfondie des arguments et gardereval
le code ed simple car il est généralement beaucoup plus difficile de maintenir et de sécuriser le code généré au moment de l'exécution.Cela étant dit, j'aime utiliser
eval
pour deux types de choses (même s'il existe probablement de meilleures alternatives, moins diaboliques):eval
s'agit d'un moyen de "mettre explicitement en cache le code", il peut être utilisé pour améliorer les performances. Notez que les optimiseurs sont toujours améliorés, mais il n'y a tout simplement aucune garantie quant à ce qu'ils peuvent faire pour vous. En rendant les choses explicites dans le code, vous pouvez réellement aider l'optimiseur à prendre des décisions plus intelligentes.Cette approche d'itérateur d'objet précompilé , par exemple, montre des avantages de performance clairs lors de l'utilisation
eval
pour l'itération de propriété d'objet. Il montre également les débuts d'un système de type puissant qui peut fournir une vérification implicite des contraintes et bien plus encore, à peu ou pas de frais.De nombreux développeurs Javascript chevronnés remarqueraient probablement qu'il s'agit d'un trou de lapin, car, si vous commencez à écrire Javascript de cette façon, vous changez essentiellement la façon dont vous utilisez le langage. Cependant, cela pourrait ne pas être nécessairement une mauvaise chose pour ceux qui aiment Javascript, mais il manque également des fonctionnalités de langage fondamentales qui ne peuvent être obtenues qu'en changeant la façon dont nous utilisons le langage lui-même.
la source
J'ai une situation où eval ressemble à la voie à suivre, évaluant une chaîne et renvoyant une variable existante dont le nom est le même que la chaîne.
J'ai plusieurs tables: table1ResultsTable, table2ResultsTable, tableNResultsTable. J'ai des variables configurées avec les mêmes noms, qui sont des objets datables jQuery. Je les utilise pour configurer les tables et appeler des fonctions datatable jQuery dessus.
Chaque table a assigné class = "resultsTable". Maintenant, j'ai besoin d'obtenir la variable lorsque l'on clique sur la table. Je fais ça:
Je reçois donc l'id de la table dans laquelle la cellule a été cliquée, qui a le même nom que la variable d'objet datatable qui lui correspond. Si quelqu'un a une suggestion d'amélioration, j'aimerais en savoir plus.
la source
event.target.parentElement.parentElement.parentElement
c'est horrible. De plus, je m'attendrais à ce que l'appel eval génère une erreur "erreur de référence: [id] n'est pas défini", à moins que vous n'utilisiez délibérément des identifiants évaluables (qui sont cassés, erronés et qui pourraient provoquer des choses étranges si vous finissez générer des identifiants en double).document.getElementById(ID).MySpecialProperty = MYSPECIALPROPERTYVALUE
(pour ne pas dire que c'est super non plus, mais c'est mieux que eval). Comme le souligne Eric Lippert, "chaque objet dans JScript est déjà une table de recherche."