Pourquoi les fonctionnalités de type eval sont-elles considérées comme mauvaises, par opposition à d'autres fonctionnalités potentiellement nuisibles?

51

La plupart des langues modernes (qui sont en quelque sorte interprétées) ont une sorte de fonction d' évaluation . Une telle fonction exécute un code de langue arbitraire, la plupart du temps passée comme argument principal sous forme de chaîne (différentes langues peuvent ajouter plus de fonctionnalités à la fonction eval).

Je comprends que les utilisateurs ne devraient pas être autorisés à exécuter cette fonction ( modifier, c'est-à-dire prendre directement ou indirectement une entrée arbitraire d'un utilisateur arbitraire à transférer eval), en particulier avec un logiciel côté serveur, car ils pourraient forcer le processus à exécuter du code malveillant. De cette manière, les tutoriels et les communautés nous disent de ne pas utiliser eval. Cependant, eval est souvent utile et utilisé:

  • Règles d'accès personnalisées aux éléments logiciels (IIRC OpenERP dispose d'un objet ir.rulepouvant utiliser du code python dynamique).
  • Calculs et / ou critères personnalisés (OpenERP a des champs comme celui-ci pour permettre des calculs de code personnalisés).
  • Analyseurs de rapport OpenERP (oui, je sais que je vous fais peur avec OpenERP, mais c’est le principal exemple que j’ai).
  • Coder les effets des sorts dans certains jeux de rôle.

Ils sont donc utiles, dans la mesure où ils sont utilisés correctement. L'avantage principal est que cette fonctionnalité permet aux administrateurs d'écrire du code personnalisé sans avoir à créer davantage de fichiers et à les inclure (bien que la plupart des frameworks utilisant des fonctionnalités eval disposent également d'un moyen de spécifier un fichier, un module, un package, ... à lire).

Cependant, eval est un mal dans la culture populaire. On pense à des choses comme une intrusion dans votre système.

Cependant, il existe d'autres fonctions qui pourraient être néfastes si les utilisateurs y avaient accès: déconnexion, lecture, écriture (sémantique de fichier), allocation de mémoire et arithmétique de pointeur, accès au modèle de base de données (même sans prendre en compte les cas injectables en SQL).

Donc, en gros, la plupart du temps quand tout code est pas écrit correctement ou non surveillé correctement (ressources, les utilisateurs, les environnements, ...), le code est mal et peut même conduire à l' impact économique.

Mais il y a quelque chose de spécial avec les evalfonctions (quelle que soit la langue).

Question : Existe-t-il un fait historique pour que cette peur fasse partie de la culture populaire, au lieu d’accorder la même attention à d’autres caractéristiques potentiellement dangereuses?

Luis Masuelli
la source
11
Je ne suis pas d'accord sur le fait que cela est trop large et, à titre de preuve, je présente les quatre réponses d'une longueur raisonnable.
12
Ils ont voté pour fermer comme trop large ? (Je ne vois pas encore de votes serrés dans cette communauté). Cette raison proche est en train de devenir une raison générique qui n'a aucun sens ces derniers temps. Particulièrement lorsque le point que je pose est assez clair avec des exemples et un point spécifique à poser. Je vais demander à ce sujet dans Meta ...
Luis Masuelli
13
Pourquoi cela fait-il partie de la culture populaire, avec plus d'attention que d'autres caractéristiques dangereuses? Parce que l'allitération eval - le mal est facile à retenir
Bergi
5
L'affectation de mémoire et l'arithmétique de pointeur sont considérées comme mauvaises par beaucoup.
user253751
5
Il convient de noter qu'OpenERP (maintenant Odoo) ne fait pas qu'appeler eval, il dispose d'une fonction interne appelée safe_evalqui prépare l'environnement à empêcher le code de faire des choses dangereuses. Des bogues ont été trouvés, cependant, car Python est un langage assez flexible, et donc difficile à contrôler.
André Paramés

Réponses:

76

Une evalfonction en elle-même n'est pas mauvaise, et il y a un point subtil que je ne crois pas que vous faites valoir:

Autoriser un programme à exécuter des entrées utilisateur arbitraires est mauvais

J'ai écrit un code qui utilisait un evaltype de fonction et qui était sécurisé: le programme et les paramètres étaient codés en dur. Parfois, il n’existe aucune fonctionnalité de langue ou de bibliothèque permettant de répondre aux besoins du programme; l’exécution d’une commande shell est le chemin court. "Je dois finir de coder cela en quelques heures, mais écrire de Java / .NET / PHP / n'importe quel code prendra deux jours. Ou je peux le evalfaire en cinq minutes."

Une fois que vous autorisez les utilisateurs à exécuter tout ce qu'ils veulent, même s'ils sont verrouillés par des privilèges utilisateur ou derrière un écran "sécurisé", vous créez des vecteurs d'attaque. Chaque semaine, un CMS, un logiciel de blogging, etc. au hasard comporte une faille de sécurité qui permet à un attaquant d'exploiter une telle faille. Vous comptez sur la totalité de la pile de logiciels pour protéger l'accès à une fonction pouvant être utilisée rm -rf /ou à une autre tâche catastrophique (remarque: cette commande a peu de chances de réussir, mais elle échouera après avoir causé un petit dommage).

Y a-t-il un fait historique pour que cette peur fasse partie de la culture populaire, au lieu de porter la même attention sur d'autres caractéristiques potentiellement dangereuses?

Oui, il y a un précédent historique. En raison des nombreux bogues corrigés au fil des ans dans divers logiciels permettant à des attaquants distants d’exécuter du code arbitraire, l’idée de l’opération evalest tombée en désuétude. Les langages et les bibliothèques modernes possèdent de nombreuses fonctionnalités qui la rendent evalmoins importante, et ce n’est pas un hasard. Cela rend les fonctions plus faciles à utiliser et réduit le risque d’exploitation.

Une grande attention a été portée à de nombreuses fonctionnalités potentiellement peu sûres dans les langages populaires. La question de savoir si une personne reçoit plus d’attention est avant tout une question d’opinion, mais les evalfonctionnalités présentent certainement un problème de sécurité prouvable et facile à comprendre. D'une part, ils permettent d'exécuter des commandes du système d'exploitation, notamment les commandes intégrées au shell et les programmes externes standard (par exemple rmou del). Deux, combiné à d’autres exploits, un attaquant peut télécharger son propre script exécutable ou shell, puis l’exécuter via votre logiciel, ouvrant ainsi la porte à presque tout ce qui se passe (rien de bon).

C'est un problème difficile. Le logiciel est complexe et une pile de logiciels (par exemple, LAMP ) est constituée de plusieurs logiciels interagissant de manière complexe. Faites attention à la manière dont vous utilisez les fonctionnalités de langage telles que celle-ci et n'autorisez jamais les utilisateurs à exécuter des commandes arbitraires.


la source
2
Vous êtes le seul :). Bien que s’il existe un bon exemple bien connu qui ait contribué à cette culture, j’aimerais le voir dans la réponse.
Luis Masuelli
5
Je ne suis pas au courant de tout seul exemple, je crois que cela est plus « mort par mille coupures » avec de nombreux petits exemples d'exploits utilisés et patché. Je n'exagère pas en disant qu'un exploit à distance est corrigé chaque semaine dans un logiciel.
1
Mon IDE est un programme qui me permet - son utilisateur - d’exécuter des entrées arbitraires. Je trouve cela utile plutôt que mauvais.
Den
3
@ Den, ce serait une exception. Étant un IDE, je suis sûr que vous pourriez causer du chaos sans cette capacité. Il suffit de l'écrire dans votre code source. En outre, vous avez déjà un accès complet à l'ordinateur sur lequel il s'exécute. L'implication ici est qu'un an evalpeut élever des privilèges. ce qui n'est pas un problème s'ils sont déjà élevés.
3
@ Den: C'est ce que Raymond Chen a résumé comme "l'autre côté du sas". Vous pouvez déjà courir rm -rf /, il n’est pas nécessaire de le faire de manière compliquée via un IDE. Le problème, evalc'est que cela ouvre cette capacité à beaucoup d'acteurs qui ne devraient pas en avoir.
MSalters
38

Une partie de cela est simplement que la nuance est difficile. Il est facile de dire que ne jamais utiliser goto, des champs publics, une interpolation de chaîne pour des requêtes SQL ou eval. Ces déclarations ne doivent pas être comprises comme indiquant qu'il n'y a jamais, en aucune circonstance, de raison de les utiliser. Mais les éviter en règle générale est une bonne idée.

Eval est fortement découragé car il combine plusieurs problèmes communs.

Premièrement, il est sujet aux attaques par injection. Ici, c'est comme l'injection SQL en ce que lorsque des données contrôlées par l'utilisateur sont insérées dans le code, il est facile de permettre accidentellement l'insertion de code arbitraire.

Deuxièmement, les débutants ont tendance à utiliser eval pour contourner un code mal structuré. Un codeur débutant pourrait écrire un code qui ressemble à:

x0 = "hello"
x1 = "world"
x2 = "how"
x3 = "are"
x4 = "you?"
for index in range(5):
   print eval("x" + index)

Cela fonctionne, mais c'est vraiment la mauvaise façon de résoudre ce problème. Évidemment, utiliser une liste serait bien mieux.

Troisièmement, eval est généralement inefficace. Beaucoup d’efforts sont consacrés à l’accélération de la mise en œuvre de notre langage de programmation. Mais eval est difficile à accélérer et son utilisation aura généralement des effets néfastes sur vos performances.

Donc, eval n'est pas mauvais. Nous pourrions dire que eval est diabolique, car bon, c’est une façon accrocheuse de le dire. Tout codeur débutant doit absolument rester à l’écart de eval car, quoi qu’ils veuillent faire, eval est presque certainement la mauvaise solution. Pour certains cas d'utilisation avancés, eval a du sens, et vous devriez l'utiliser, mais évidemment, faites attention aux pièges.

Winston Ewert
la source
13
Votre deuxième cas est très important. Dans les langues qui ont eval mais sont également compilées, évaluer une chaîne pour produire une référence de variable n'est pas trivial. Par exemple, si var x = 3; print(x)est compilé, il n'est pas nécessaire que le code source sache que la source a utilisé le nom "x". Pour var x = 3; print(eval("x"))pouvoir fonctionner, ce mappage doit être enregistré. C'est un problème réel: dans Common Lisp (let ((x 3)) (print (eval 'x))), une exception de variable non liée sera levée, car la variable lexicale x n'a aucun lien avec le nom une fois le code compilé.
Joshua Taylor
@JohnuaTaylor Vous voulez dire la troisième raison, pas la deuxième?
user253751
1
@immibis, je pense qu'il fait référence au code dans la deuxième raison. Mais vous avez raison, cela concerne vraiment la troisième raison: la performance.
Winston Ewert
Vu cette question , n'est-ce pas? ;)
jpmc26
@ jpmc26, no. Mais j'en ai vu beaucoup comme ça.
Winston Ewert
20

Cela revient à dire que "l'exécution de code arbitraire" est tech-talk pour "capable de faire n'importe quoi". Si quelqu'un est capable d'exploiter l'exécution de code arbitraire dans votre code, il s'agit littéralement de la pire vulnérabilité de sécurité possible, car cela signifie qu'il est capable de faire tout ce que votre système peut faire.

Les "autres bogues potentiellement dangereux" peuvent avoir des limites, ce qui signifie qu'ils sont, par définition, moins dommageables qu'une exécution de code arbitraire exploitée.

Maçon Wheeler
la source
2
Par souci d'argumentation, l'utilisation abusive de pointeurs conduit également à l'exécution de code arbitraire , mais les pointeurs sont mal vus bien moins que ce evaln'est le cas.
Dmitry Grigoryev
12
@DmitryGrigoryev Sont-ils vraiment? En dehors de C ++, les pointeurs sont généralement considérés comme extrêmement dangereux et évités. C # prend en charge les pointeurs, par exemple, mais c'est généralement la dernière chose que vous essayez d'essayer après avoir épuisé toutes les autres options (généralement, pour des raisons de performances lors de la manipulation de données). La plupart des langues modernes ne prennent pas en charge les pointeurs. Même le C ++ lui-même évolue vers des pointeurs "plus sûrs" qui tentent de résoudre les problèmes avec des pointeurs arbitraires (par exemple, en utilisant des listes / tableaux vrais au lieu de simplement des pointeurs, en utilisant safe_ptr, le passage de référence ...).
Luaan
2
@DmitryGrigoryev: Pouvez-vous fournir une référence à quiconque affirmant que les pointeurs sont moins dangereux que eval?
JacquesB
2
@JacquesB vous voilà :)
Dmitry Grigoryev Le
1
@ JacquesB, oui; c'était censé être une blague (je m'attendais à ce que le sourire soit assez clair). Le PO a fait cette déclaration, pas moi, vous devriez donc lui demander une preuve.
Dmitry Grigoryev
15

Il y a une raison pratique et une raison théorique.

La raison pratique est que nous observons que cela pose souvent des problèmes. Il est rare que eval aboutisse à une bonne solution et aboutit souvent à une mauvaise solution: vous en auriez une meilleure si vous aviez prétendu que eval n'existait pas et que vous abordiez le problème différemment. Donc, le conseil simplifié consiste à l'ignorer, et si vous proposez un cas dans lequel vous souhaitez ignorer le conseil simplifié, eh bien, espérons que vous y avez suffisamment réfléchi pour comprendre pourquoi le conseil simplifié ne s'applique pas et le point commun. les pièges ne vous toucheront pas.

La raison plus théorique est que s'il est difficile d'écrire un bon code, il est encore plus difficile d'écrire du code qui écrit un bon code. Que vous utilisiez eval ou générez des instructions SQL en collant des chaînes ou en écrivant un compilateur JIT, ce que vous tentez est souvent plus difficile que prévu. Le potentiel d’injection de code malveillant est une partie importante du problème, mais mis à part cela, il est généralement plus difficile de connaître le code correct si votre code n’existe même pas avant l’exécution. Le conseil simplifié est donc de vous simplifier la vie: "utiliser des requêtes SQL paramétrées", "ne pas utiliser eval".

Exemple: utilisez un compilateur ou un interprète Lua (ou autre) dans votre jeu pour permettre aux concepteurs de jeux de disposer d’un langage plus simple que C ++ (ou autre) pour décrire les effets de sorts. La plupart des "problèmes d'eval" ne s'appliquent pas si vous ne faites qu'évaluer un code qui a été écrit, testé et inclus dans le jeu, dans le DLC ou ce que vous avez. C'est juste mélanger les langues. Les gros problèmes que vous rencontrez lorsque vous essayez de générer Lua (ou C ++, SQL, ou des commandes de shell, etc.) à la volée, et de le gâcher.

Steve Jessop
la source
1
Bien entendu, la génération de code d'exécution peut être effectuée correctement et eval peut être utile. Par exemple, j'utilise fréquemment eval pour des métaprogrammations / des opérations de type macro, en particulier lorsque je souhaite plus de performances que ne le permet une solution OOP «plus propre» ou fonctionnelle. Le code qui en résulte est souvent meilleur et plus simple car a moins de passe-passe. Cependant, être conscient de divers problèmes concernant le sandboxing, les mécanismes d'échappement, l'injection de code, les règles de délimitation, le signalement des erreurs, l'optimisation, etc. nécessite un niveau non négligeable de maîtrise de la langue, et eval est réellement dangereux sans cette connaissance.
amon
11

Non, il n'y a pas de fait historique évident.

Les maux d’éval sont évidents depuis le début. D'autres caractéristiques sont légèrement dangereuses. Les gens peuvent supprimer des données. Les gens peuvent voir des données qu'ils ne devraient pas. Les gens peuvent écrire des données qu'ils ne devraient pas. Et ils ne peuvent faire la plupart de ces choses que si vous vous trompez et ne validez pas les entrées de l'utilisateur.

Avec eval, ils peuvent pirater le pentagone et lui donner l’impression de le faire. Ils peuvent inspecter vos frappes au clavier pour obtenir vos mots de passe. En supposant un langage complet de Turing, ils peuvent littéralement faire tout ce que votre ordinateur est capable de faire.

Et vous ne pouvez pas valider l'entrée. C'est une chaîne de forme libre arbitraire. Le seul moyen de le valider serait de construire un analyseur et un moteur d'analyse de code pour le langage en question. Bonne chance avec ça.

Telastyn
la source
1
... ou que l'entrée provienne d'une source fiable, telle que les fichiers de définition orthographique d'un jeu.
user253751
3
@immibis mais si l'entrée est prédéfinie et testée en toute sécurité, pourquoi utiliser eval alors qu'elle pourrait être incluse dans la source du système?
Jules
3
@immibis - Parce que personne ne pirate jamais les fichiers de jeu ...
Telastyn
2
... ce n'est pas ce que signifie "Turing complet" (la complétude de Turing est un pas en avant de l'informatique non pertinente à la réalité).
Leushenko
1
@Telastyn: Ce qu'un programme Javascript ne peut pas faire. Ou même un programme C ++. Javascript s'exécute dans un sandbox (navigateur) lui-même situé dans un autre sandbox (anneau 3 en x86). Le vecteur d'interruption est en dehors de ce bac à sable, sous le contrôle du système d'exploitation. Et ce sandbox externe, anneau 3, est appliqué par le processeur.
MSalters
6

Je pense que cela se résume aux aspects suivants:

  • Nécessité
  • Utilisation (surveillée)
  • Accès
  • Vérifiabilité
  • Attaques en plusieurs étapes

Nécessité

Bonjour, j'ai écrit cet outil d'édition d'images extrêmement cool (disponible pour 0,02 USD). Une fois l'image ouverte, vous pouvez passer une multitude de filtres sur votre image. Vous pouvez même en programmer vous-même en utilisant Python (le programme dans lequel j'ai écrit l'application). Je vais simplement utiliser evalvotre saisie, en vous confiant d'être un utilisateur respectable.

(plus tard)

Merci de l'avoir acheté. Comme vous pouvez le constater, il fonctionne exactement comme je l'ai promis. Oh, tu veux ouvrir une image? Non, tu ne peux pas. Je n'utiliserai pas la readméthode car elle est quelque peu précaire. Économie? Non, je ne vais pas utiliser write.

Ce que j'essaie de dire est: vous avez besoin de lire / écrire pour presque les outils de base. Même chose pour stocker les meilleurs scores de votre jeu si génial.

Sans lecture / écriture, votre éditeur d'image est inutile. Sans eval? Je vais vous écrire un plugin personnalisé pour ça!

Utilisation (surveillée)

De nombreuses méthodes peuvent être potentiellement dangereuses. Comme par exemple le readet write. Un exemple courant est un service Web vous permettant de lire des images d’un répertoire spécifique en spécifiant le nom. Cependant, le "nom" peut en fait être n'importe quel chemin d'accès (relatif) valide sur le système, ce qui vous permet de lire tous les fichiers auxquels le service Web a accès, pas seulement les images. Abuser de cet exemple simple est appelé "parcours transversal". Si votre application autorise la traversée de chemins, c'est mauvais. Un readsans se défendre contre la traversée d'un chemin peut être appelé le mal.

Cependant, dans d'autres cas, la chaîne for readest entièrement sous le contrôle des programmeurs (peut-être codée en dur?). Dans ce cas, ce n’est guère mal à utiliser read.

Accès

Maintenant, un autre exemple simple, en utilisant eval.

Quelque part dans votre application Web, vous voulez du contenu dynamique. Vous allez permettre aux administrateurs de saisir un code exécutable. Étant donné que les administrateurs sont des utilisateurs de confiance, cela peut théoriquement être correct. Assurez-vous simplement de ne pas exécuter le code soumis par des non-administrateurs, et tout va bien.

(C'est-à-dire, jusqu'à ce que vous ayez renvoyé ce sympathique administrateur mais que vous ayez oublié de révoquer son accès. Maintenant, votre application web est mise à la corbeille).

Vérifiabilité.

Je pense qu'un autre aspect important est la facilité de vérification des entrées de l'utilisateur.

Vous utilisez une entrée utilisateur dans un appel en lecture? Assurez-vous simplement (très) que l'entrée pour l'appel de lecture ne contient rien de malveillant. Normalisez le chemin et vérifiez que le fichier ouvert se trouve dans votre répertoire de supports. Maintenant c'est sûr.

Entrée de l'utilisateur lors d'un appel en écriture? Même!

Injection SQL? Échappez-vous-en ou utilisez des requêtes paramétrées et vous êtes en sécurité.

Eval? Comment allez-vous vérifier l'entrée utilisée pour l' evalappel? Vous pouvez travailler très fort, mais c'est vraiment très difficile (voire impossible) de le faire fonctionner en toute sécurité.

Attaques en plusieurs étapes

Maintenant, chaque fois que vous utilisez une entrée utilisateur, vous devez peser les avantages de son utilisation par rapport aux dangers. Protégez son utilisation autant que vous le pouvez.

Considérons à nouveau les evaléléments capables dans l'exemple d'administration. Je vous ai dit que c'était en quelque sorte ok.

Maintenant, considérez qu'il y a effectivement un endroit dans votre application web où vous avez oublié d'échapper au contenu utilisateur (HTML, XSS). C'est une infraction moins grave qu'une évaluation accessible à l'utilisateur. Mais, en utilisant le contenu d'utilisateur non échappé, un utilisateur peut prendre en charge le navigateur Web d'un administrateur et ajouter un evalblob actif dans la session des administrateurs, permettant ainsi à nouveau un accès complet au système.

(La même attaque en plusieurs étapes peut être effectuée avec une injection SQL à la place de XSS, ou des écritures de fichiers arbitraires remplaçant le code exécutable au lieu de les utiliser eval)

Postme de Sjoerd Job
la source
2
"Vous pouvez travailler très dur, mais c'est vraiment très difficile (voire impossible) de le faire fonctionner en toute sécurité." - Il est impossible. Preuve simple: au lieu d'essayer de déterminer si le code fourni par l'utilisateur est "sécurisé", essayez simplement de trouver quelque chose de beaucoup, beaucoup plus simple, et voyez à quel point c'est déjà difficile : le code fourni par l'utilisateur est-il interrompu?
Jörg W Mittag
2
@ JörgWMittag: donnez-moi un programme écrit en Coq et je le prouverai.
André Paramés
1
@ JörgWMittag: d'accord. Selon la langue et l'étendue de la saisie de l'utilisateur. Cela pourrait aussi bien être eval("hard coded string" + user_input_which_should_be_alphanumeric + "remainder"). Il est possible de vérifier que l'entrée est alphanumérique. De plus, "Est-ce que ça s'arrête" est orthogonal à "Est-ce qu'il modifie / n'accède pas à l'état qu'il ne devrait pas toucher" et "Est-ce que cela appelle des méthodes qu'il ne devrait pas appeler".
Sjoerd Job Postmus Le
3
@ JörgWMittag Il est impossible de prouver qu'un programme donné ne fera rien, mais il n'est pas impossible de définir de manière conservatrice un ensemble restreint de programmes pour lesquels vous pouvez le prouver, et de faire en sorte que les programmes d'entrée en soient membres.
user253751
3

Pour que cette fonctionnalité fonctionne, cela signifie que je dois conserver une couche de réflexion permettant un accès complet à l'état interne du programme.

Pour les langages interprétés, je peux simplement utiliser l'état interpréteur, ce qui est facile, mais combiné aux compilateurs JIT, il augmente encore considérablement la complexité.

Sans cela eval, le compilateur JIT peut souvent prouver que les données locales d'un thread ne sont pas accessibles à partir d'un autre code. Il est donc parfaitement acceptable de réorganiser les accès, d'omettre les verrous et de mettre en cache les données souvent utilisées plus longtemps. Lorsqu'un autre thread exécute une evalinstruction, il peut s'avérer nécessaire de synchroniser le code compilé JIT en cours d'exécution avec celui-ci. Par conséquent, le code généré par JIT a besoin d'un mécanisme de secours qui retourne à une exécution non optimisée dans un laps de temps raisonnable.

Ce type de code a tendance à avoir beaucoup de bugs subtils, difficiles à reproduire, et en même temps, il limite également l'optimisation dans le compilateur JIT.

Pour les langages compilés, le compromis est encore pire: la plupart des optimisations sont interdites et je dois conserver des informations sur les symboles et un interprète, de sorte que la flexibilité supplémentaire ne vaut généralement pas la peine - il est souvent plus facile de définir une interface avec certains serveurs internes. structures, par exemple en donnant à la vue de script et au contrôleur un accès simultané au modèle du programme .

Simon Richter
la source
"Pour que cette fonctionnalité fonctionne, cela signifie que je dois conserver une couche de réflexion permettant un accès complet à l'état interne du programme" - non, uniquement aux parties que vous souhaitez affecter. Dans le cas d’OpenERP / Odoo, le code en cours d’évaluation n’a accès qu’à un nombre très limité de variables et de fonctions qu’il peut appeler, et elles sont toutes thread-locales.
André Paramés
1

Je rejette la prémisse qui evalest considérée comme plus diabolique que l'arithmétique de pointeur ou plus dangereuse que l'accès direct à la mémoire et au système de fichiers. Je ne connais aucun développeur avisé qui pourrait croire cela. De plus, les langages prenant en charge l’arithmétique de pointeur / l’accès direct à la mémoire ne prennent généralement pas en charge, evalet inversement, je tiens donc à préciser à quelle fréquence une telle comparaison serait même pertinente.

Mais evalpeut-être une vulnérabilité plus connue , pour la simple raison qu’elle est supportée par JavaScript. JavaScript est un langage en mode bac à sable sans accès direct à la mémoire ou au système de fichiers. Par conséquent, il ne dispose tout simplement pas de ces vulnérabilités, ce qui limite les faiblesses de la mise en œuvre du langage lui-même. Evalest donc l’une des caractéristiques les plus dangereuses du langage, car elle ouvre la possibilité d’une exécution arbitraire du code. Je crois que beaucoup plus de développeurs développent en JavaScript qu'en C / C ++, il evalest donc tout simplement plus important de savoir que les débordements de mémoire tampon pour la majorité des développeurs.

JacquesB
la source
0

Aucun programmeur sérieux ne considérerait Eval comme "mal". C'est simplement un outil de programmation, comme un autre. La crainte (s'il y a une crainte) de cette fonction n'a rien à voir avec la culture populaire. Il s'agit simplement d'une commande dangereuse, souvent mal utilisée, qui peut créer de graves failles de sécurité et dégrader les performances. D'après ma propre expérience, je dirais qu'il est rare de rencontrer un problème de programmation qui ne puisse être résolu de manière plus sûre et efficace par d'autres moyens. Les programmeurs les plus susceptibles d'utiliser eval sont ceux qui sont probablement les moins qualifiés pour le faire en toute sécurité.

Cela dit, il existe des langues où l’utilisation d’eval est appropriée. Perl vient à l'esprit. Cependant, je trouve personnellement que c'est très rarement nécessaire dans d'autres langues plus modernes, qui prennent en charge de manière native la gestion structurée des exceptions.

utilisateur1751825
la source
cela n'essaye même pas de répondre à la question posée: "Existe-t-il un fait historique pour que cette peur fasse partie de la culture populaire". Voir Comment répondre
Gnat
La question, à mon avis, est basée sur une fausse prémisse, alors j’ai répondu comme telle.
user1751825
0

Je pense que vous couvrez assez bien la partie suivante de votre question (c'est moi qui souligne):

ils ont un bon usage, tant qu'ils sont utilisés correctement

Pour les 95% qui l'utilisent correctement, c'est très bien; mais il y aura toujours des gens qui ne l'utilisent pas correctement. Certains d’entre eux devront faire preuve d’inexpérience et de capacités, le reste sera malicieux.

Il y aura toujours des gens qui veulent repousser les limites et trouver des failles de sécurité, certaines pour le bien, d'autres pour le mal.

En ce qui concerne les faits historiques, evalles fonctions de type permettent essentiellement l’ exécution de code arbitraire qui était auparavant exploité dans le populaire CMS Web, Joomla! . Avec Joomla! alimentant plus de 2,5 millions de sites dans le monde , cela représente un dommage potentiel non seulement pour les visiteurs de ces sites, mais aussi pour l'infrastructure hébergée et la réputation des sites / entreprises exploités.

Le Joomla! Cet exemple peut être simple, mais c’est un enregistrement.

gabe3886
la source
0

Il y a de bonnes raisons de décourager l'utilisation de eval(bien que certaines soient spécifiques à certaines langues).

  • L’environnement (lexiquement et dynamiquement) utilisé par evalest souvent surprenant (c’est-à-dire que vous eval(something here)devriez faire une chose mais en faire une autre, en déclenchant éventuellement des exceptions)
  • Il y a souvent un meilleur moyen de réaliser la même chose (la concaténation de fermetures lexicales construites est parfois une meilleure solution, mais cela peut être spécifique à Common Lisp)
  • Il est beaucoup trop facile de se retrouver avec des données non sécurisées en cours d’évaluation (bien que cela puisse généralement être évité).

Personnellement, je n'irais pas jusqu'à dire que c'est mal, mais je contesterai toujours l'utilisation d' evalune révision de code, avec le libellé du type "avez-vous envisagé un code ici ?" (si j’ai le temps de faire au moins un remplacement provisoire) ou "êtes-vous sûr qu’une évaluation est vraiment la meilleure solution ici?" (si je ne le fais pas)

Vatine
la source
cela n'essaye même pas de répondre à la question posée: "Existe-t-il un fait historique pour que cette peur fasse partie de la culture populaire". Voir Comment répondre
Moucheron
0

Dans Society of Mind , chapitre 6.4, de Minsky , il déclare

Il y a un moyen pour un esprit de se surveiller tout en gardant une trace de ce qui se passe. Divisez le cerveau en deux parties, A et B. Connectez les entrées et les sorties du cerveau A au monde réel - afin qu'il puisse ressentir ce qui s'y passe. Mais ne connectez pas le cerveau B au monde extérieur du tout; connectez-le plutôt pour que le cerveau A soit le monde du cerveau B!

Lorsqu'un programme (B) écrit un autre programme (A), il fonctionne comme un méta-programme. Le sujet de B est le programme A.

Il y a un programme en C. C'est celui dans votre tête qui écrit le programme B.

Le danger est qu'il peut y avoir quelqu'un (C ') avec une intention malveillante, qui peut interférer dans ce processus, de sorte que vous obtenez des choses comme l'injection de SQL.

Le défi consiste à rendre les logiciels plus intelligents sans les rendre également plus dangereux.

Mike Dunlavey
la source
Deux votes positifs et deux votes négatifs. On dirait que cela frappe peut-être.
Mike Dunlavey
0

Vous avez beaucoup de bonnes réponses ici et la raison principale est clairement que l'exécution de code arbitraire est mauvaise, mais j'ajouterai un autre facteur que d'autres n'ont abordé que de façon marginale:

Il est très difficile de dépanner le code en cours d’évaluation à partir d’une chaîne de texte. Vos outils de débogage normaux sortent presque de la fenêtre et vous êtes réduit au traçage ou à l'écho très traditionnel. Évidemment, cela n'a pas tellement d'importance si vous avez un fragment dans une ligne que vous voulez, evalmais en tant que programmeur expérimenté, vous pouvez probablement trouver une meilleure solution pour cela, alors que la génération de code à grande échelle peut être quelque part qu'une fonction d'évaluation devient un allié potentiellement utile.

glénatron
la source