Question:
Variables globales et sécurité de l'information
user123574
2019-09-02 23:58:53 UTC
view on stackexchange narkive permalink

J'ai l'impression que c'est une meilleure pratique de programmation pour créer des variables dans des portées spécifiques (comme une portée de fonction) et éviter la portée globale pour rendre les choses plus modulaires et mieux organisées. Cependant, je ne suis pas sûr qu'il y ait aussi un problème de sécurité.

Voici un exemple de variables globales dans Bash qui ont bien fonctionné pour moi plus d'un an:

  cat <<-EOF >> "$ HOME" /. profile set -x complete -r export war = "/ var / www / html" # Web Application Root; export dmp = "phpminiadmin" # Programme de gestion de base de données; export -f war war () {cd $ war /} EOFsource "$ HOME" /. profile 2> / dev / null  

Je n'ai jamais eu de problème avec les variables globales dans Bash ou JavaScript , probablement parce que je n'ai écrit que de petits scripts pour un usage personnel sur des environnements minimalistes.

Pourquoi de nombreux programmeurs évitent d'utiliser des variables globales et y a-t-il des exemples de failles de sécurité causées par l'utilisation de variables globales?

* "Pourquoi de nombreux programmeurs s'abstiennent d'utiliser des variables globales?" * - parce qu'il est beaucoup plus facile de comprendre et de vérifier de petits extraits de code qui n'ont aucun effet secondaire.Lorsque vous utilisez des variables globales, vous devez toujours savoir quelle partie du code pourrait le changer de quelle manière et quel en sera l'effet - ce qui est vraiment difficile avec une base de code plus large et plus que des variables globales triviales sans comportement évident (c.-à-d.la variable de débogage peut convenir).Voir aussi [Les variables globales sont mauvaises] (http://wiki.c2.com/?GlobalVariablesAreBad).
Problèmes de threading, sinon des problèmes de concurrence s'ensuivent
Les variables globales sont plus courantes que vous ne le pensez.Les champs statiques Java sont effectivement globaux et largement utilisés.Ils conviennent parfaitement aux constantes ou aux éléments qui viennent d'être attribués lors de l'initialisation.Les problèmes viennent avec des globaux mutables.
Une idée plus générale des raisons pour lesquelles les développeurs détestent les variables globales est qu'elles peuvent provoquer une "action à distance" https://en.wikipedia.org/wiki/Action_at_a_distance_(computer_programming)
Il n'y a vraiment rien de mal avec les variables globales si vous n'écrivez que de "petits" scripts.C'est lorsque vous créez des scripts ou des programmes de taille moyenne à grande qu'ils deviennent un cauchemar.
En relation avec le génie logiciel: [Pourquoi l'état mondial est-il si mal?] (Https://softwareengineering.stackexchange.com/questions/148108/why-is-global-state-so-evil) Un certain nombre des problèmes mentionnés ici pourraient égalementconduire à des problèmes de sécurité.
@whatsisname Même avec de petits scripts, cela peut être un problème avec plusieurs développeurs.S'ils décident tous les deux d'utiliser le même nom pour une variable globale, mais que son objectif est différent, vous rencontrerez des problèmes.
Je pense qu'un script shell de 8 lignes (après génération qui a encore moins de variables et utilise uniquement des variables maintenues par le système) sans concurrence n'est pas le meilleur exemple pour discuter des concepts de génie logiciel qui existent principalement pour rendre une grande base de code modulaire mieux compréhensible, surtout pas siil ne contient que des affectations de variables immuables (constantes).D'autant plus qu'il peut être remplacé par un seul alias de ligne, dans ce cas.
Comme vous mentionnez Javascript, c'est un cas particulier car les variables globales sont visibles et modifiables via la console des outils de développement
Tangentiellement, vos guillemets manquants dans la définition de la fonction `war` sont également un anti-modèle de sécurité.Voir [Implications de sécurité de l'oubli de citer une variable dans les shells bash / POSIX] (https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells) sur [unix.se]
Dix réponses:
Conor Mancone
2019-09-03 01:18:17 UTC
view on stackexchange narkive permalink

Boycottez les globaux!

Je vole le commentaire de Steffen Ullrich, mais le principal problème avec les variables globales est qu'elles rendent difficile le maintien d'un code bien organisé et maintenable. Son lien est parfait, mais vous n'aurez aucun mal à trouver d'innombrables articles sur les problèmes liés aux variables globales en ligne.

Lorsque vous utilisez des variables globales, il devient facile de perdre la trace de l'endroit où dans votre programme la variable est modifiée, surtout si vous n'avez pas de flux linéaire simple. En conséquence, les variables globales peuvent parfaitement fonctionner dans de petits scripts, mais peuvent causer d'énormes maux de tête lorsqu'une application commence à évoluer.

La principale raison pour laquelle j'éviterais les globaux est parce qu'elles font des tests unitaires / d'intégration automatisés un cauchemar. Les petites applications peuvent survivre sans tests, mais essayer de gérer une application plus grande sans de bons tests n'est qu'un cauchemar (croyez-moi, j'ai essayé dans mes jours jeunes et insensés).

Cela pourrait vous laisser avec le l'impression que les globaux sont bons dans les très petites applications, mais comme les applications ne se développent généralement qu'avec le temps et que les choses qui commencent temporairement deviennent permanentes, c'est vraiment une mauvaise idée de les utiliser. Pourquoi partir du mauvais pied, alors qu’il est si facile d’utiliser des variables correctement étendues?

Sécurité

L’utilisation de variables globales n’a pas d’implications directes pour la sécurité, mais ils permettent de se retrouver plus facilement avec des problèmes de sécurité:

Si un programmeur modifie une fonction dans le fichier A mais ne sait pas ou oublie que la valeur de une certaine variable de cette fonction provient de l'entrée de l'utilisateur dans le fichier B , elle pourrait finir par faire des choses non sécurisées sur l'entrée de l'utilisateur sans protections appropriées.

Global Variables == death

Je ne connais aucune violation qui se soit produite spécifiquement à cause de variables globales, mais il est facile de dire que l'utilisation de variables globales a littéralement tué des gens, donc je pense qu'il est raisonnable de ne les utilisez jamais.

Les commentaires ne sont pas destinés à une discussion approfondie;cette conversation a été [déplacée vers le chat] (https://chat.stackexchange.com/rooms/98286/discussion-on-answer-by-conor-mancone-global-variables-and-information-security).
Il peut également être intéressant de noter que de nombreux langages ne fournissent pas réellement les installations appropriées pour sécuriser les variables globales, laissant le fardeau sur le programmeur;en particulier, il n'y a généralement pas de bon moyen de limiter ce qui peut réellement y accéder et / ou les modifier.Cela pourrait également valoir la peine d'examiner les pseudo-globaux comme les contextes et la plupart des singletons, bien qu'ils aient tendance à être au moins un peu plus sûrs.
Bon vieux «Robert»);Élèves DROP TABLE; - `aka Bobby Tables
Conor, `Si un programmeur modifie une fonction dans le fichier A mais ne sait pas ou oublie que la valeur d'une certaine variable dans cette fonction provient de l'entrée utilisateur dans le fichier B, il peut finir par faire des choses non sécurisées sur l'entrée utilisateur sans un coffre-fort approprié.gardes. »Veuillez envisager de changer un peu le libellé / de le développer pour qu'il soit plus clair;Je ne suis pas sûr de n'avoir jamais travaillé sur un cas similaire, donc je ne sais pas quelle modification a causé quel dommage.
Benoit Esnard
2019-09-03 13:16:57 UTC
view on stackexchange narkive permalink

Dans certains environnements de programmation, vous ne pouvez pas faire confiance à la portée globale car d'autres sources pourraient lire / jouer avec.

Cela a déjà conduit à des vulnérabilités critiques en matière de sécurité des produits sensibles, comme une exécution de code à distance dans l'extension de navigateur LastPass .

Un JavaScript malveillant sur une page peut voler / jouer avec tout ce qu'il veut, même s'il ne se trouve pas dans une variable globale.
@JosephSible Le javascript malveillant ne peut pas voler les variables locales dans une fermeture car il n'a pas accès à cette fermeture (ce qui faisait partie de ce qui a rendu l'IIFE populaire)
@slebetman Pas directement, mais il peut faire des choses comme modifier des globaux comme `Array` ou` document` pour voler des choses indirectement.
Artelius
2019-09-03 17:02:55 UTC
view on stackexchange narkive permalink

Ils peuvent donner aux injections de code un accès plus facile à tout

En PHP, il y a le superglobal $ GLOBALS ; en Python il y a la fonction globals () , et en Javascript il y a l'objet window (ou dans Node, process ). Tout cela rend trivial l'énumération de toutes les variables globales.

Une fois que vous faites cela, vous pouvez à la fois aspirer les informations qu'elles contiennent et les modifier de manière malveillante. Par exemple, si des données sensibles sont stockées dans un global, un attaquant pourrait facilement les extraire. Si, par exemple, une URL de connexion à une base de données est stockée dans un global, un attaquant pourrait pointer l'URL pour faire référence au serveur de l'attaquant à la place, puis la victime tenterait de se connecter à ce serveur et d'envoyer des informations d'identification.

De plus, si vous avez beaucoup d ' objets globaux, vous pouvez appeler leurs méthodes facilement.

Ils violent le "principe du moindre privilège"

Ce principe de l'ingénierie de sécurité dit essentiellement "ne donnez pas à quelqu'un plus d'accès qu'il n'en a besoin pour faire son travail". Chaque fonction et méthode peut lire et écrire des variables globales même si elles ne sont absolument pas pertinentes pour son travail, ce qui signifie que si ce morceau de code est détourné, même de manière limitée, il ouvrira une plus grande surface d'attaque.

(Bien sûr, la plupart des langages de script ont des règles d'encapsulation faibles, ce qui est également une violation de POLP, mais si les objets sont hors de portée, il est beaucoup plus difficile de leur faire quoi que ce soit.)

Ils le sont. un terreau fertile pour le code bogué

Pour des raisons telles que:

  • le programmeur oubliant qu'une des variables d'une fonction est un global et donc des modifications y sont apportées persistera à la fin de la fonction,
  • la sensibilité non évidente du programme à l'ordre dans lequel les fonctions sont appelées
  • la facilité avec laquelle les échecs en cascade peuvent survenir ( par exemple, lorsqu'une fonction définit un global sur null et plus tard un autre se bloque)
  • les interactions très complexes qui peuvent se produire facilement et sur lesquelles il est difficile de raisonner

Elles sont tout simplement désordonnées

Si vous pensez à une entreprise où il y a des papiers éparpillés partout, les choses ne sont pas organisées et rangées proprement mais juste traîner, qui va remarquer si quelque chose manque? Si un employé commet une fraude, personne ne remarquera l'écart, car les écarts sont partout. Si une paire de clés disparaît, quelqu'un supposera simplement qu'ils sont enterrés sous quelque chose ou que quelqu'un a dû les emprunter.

Maintenant, vous pourriez dire que c'est une exagération, mais si c'est le cas, je doute que vous ayez jamais a travaillé avec un grand projet logiciel. Les globaux sont OK si votre site Web est suffisamment petit pour être construit en quelques jours (et que vous savez ce que vous faites). Ils peuvent gagner du temps pour faire avancer quelque chose.

Mais ils ne s'adaptent pas.

Bonjour, j'aime cette réponse en général;Je n'ai pas dit que ce que vous avez écrit est une exagération;la partie "gros projet logiciel" me semble redondante et mieux à supprimer car il n'y a aucune explication à ce que vous entendez en général ou en particulier.Merci,
Bonjour à nouveau, vous êtes invités à lire mon message de prime - si vous le souhaitez.Merci,
@JohnDoea N'oubliez pas que ce site vise également à aider d'autres personnes qui _à l'avenir_ peuvent avoir fondamentalement la même question, et elles peuvent bénéficier de différentes parties d'une réponse.
Salut - humblement je ne le fais pas;Je ne suis d'accord qu'avec une partie du dernier passage ou son libellé;outre ce que j'ai dit sur la définition d'un "grand" projet;les globaux qui ne sont généralement pas corrects, peuvent rarement convenir non seulement pour la création de petits sites, mais aussi pour des "langages de programmation d'exploitation" tels que Bash (également, un constructeur de site peut travailler lentement pour créer un petit site - s'il explore un tout nouveauCMS).Cordialement.
Cette réponse semble être la meilleure pour répondre à la question spécifique sur «les variables globales causent-elles des problèmes de sécurité».Je pense que tu devrais l'accepter.
LTPCGO
2019-09-03 05:20:59 UTC
view on stackexchange narkive permalink

Veuillez comparer les morceaux de code suivants:

1)

  /file.php: $ newconn = new PDO ('mysql : host = localhost; charset = utf8mb4; ',' username ',' password ');  

2)

  ../secrets.php: $ mysqlusername = 'username'; $ mysqlpassword = 'mot de passe'; / file.php: require_once ('../ secrets.php'); $ newconn = new PDO ('mysql: host = localhost; charset = utf8mb4;', $ mysqlusername, $ mysqlpassword);  

3

  ../secrets.php: function pdoconn (i) {$ mysqlusername = ['username1', 'username2']; $ mysqlpassword = ['mot de passe1', 'mot de passe2']; $ conn = new PDO ('mysql: host = localhost; charset = utf8mb4;', $ mysqlusername [i], $ mysqlpassword [i]); return $ conn; } /file.php: require_once ('../ secrets.php'); $ newconn = pdoconn (0);  

L'exemple 1 est hors de question - une configuration incorrecte sur les serveurs de production pourrait finir par afficher des paramètres sensibles à des parties non intentionnelles.

Exemple 2 est mieux, mais ces variables sont disponibles dans toute l'application et modifiables, ce qui peut entraîner des erreurs.

L'exemple 3 garde les choses très organisées et transférables.
Il peut être modifié pour utiliser des globaux si ../ secrets.php était à la place:

  ../secrets.php:$mysqlusername = 'username'; $ mysqlpassword = 'password'; function pdoconn () {$ conn = newPDO ('mysql: host = localhost; charset = utf8mb4;', $ GLOBALS ['mysqlusername'], $ GLOBALS ['mysqlpassword']); return $ conn;}  

Et je pense que cela démontre pourquoi un global n'a pas de sens la plupart du temps de manière assez succincte.


Résumé:

En ce qui concerne les failles de sécurité utilisant des variables globales (et pourquoi j'ai écrit ces exemples en PHP), il y a eu (à l'époque) un changement controversé dans PHP 4.2.0 où register_globals était activé sur de. Je ne trouve aucun article maintenant, car ce changement a été fait en 2002, mais il me semble que je me souviens qu'il était responsable de quelques violations à l'époque. En copiant directement à partir du manuel, il existe un exemple très clair de code vulnérable:

  <? Php // définir $ autorisé = true uniquement si l'utilisateur est authentifiéif (authenticated_user ()) {$ autorisé = true;} // Parce que nous n'avons pas initialisé $ autorisé comme faux, cela pourrait // être défini via register_globals, comme dans GET auth.php? allowed = 1 // Donc, n'importe qui peut être vu comme authentifié! if ($ autorisé) {include "/highly/sensitive/data.php";}?>  
Je dirais que le n ° 3 est également mauvais, car le mot de passe est dans le code source!Vous rencontrez toujours les mêmes problèmes d'exposition accidentelle.Excellent exemple à la fin!
@Anders peut-être que ce n'est pas clair, où je dois garder le fichier sur le même serveur, j'utilise une fonction similaire à celle-ci au lieu d'avoir simplement une variable avec le mot de passe stocké dans un fichier, car lorsque cela est inclus, il est normalement disponible dans le monde entier.Essentiellement, vous gardez le même que ce que je pense que vous suggérez, mais au lieu de faire référence à une variable lorsque cela est nécessaire, vous appelez plutôt une fonction pour renvoyer l'objet requis.
Mon point est que vous ne devez pas du tout conserver les mots de passe dans le code source, même si c'est dans une fonction.
Je dis que ce n'est pas dans le code source cependant, il se trouverait dans un fichier quelque part sur le serveur que vous incluez_once ().À moins que vous ne parliez de ne pas conserver le mot de passe sur le serveur du tout et d'accéder aux informations d'identification via une API, ce que je suis à 100% d'accord et que je vise à faire dans toutes les situations où cela peut être fait.
`L'exemple 1 illustre comment une configuration incorrecte sur les serveurs de production pourrait finir par afficher des valeurs de paramètres sensibles à des parties non intentionnelles. 'Voulez-vous dire que les deux valeurs apparaissent dans les chaînes de requête?
@JohnDoea dans certains langages de script, si le script échoue sur une certaine ligne, cette ligne est envoyée à stdout à l'utilisateur.Si la ligne contient un mot de passe, le mot de passe sera envoyé à stdout.
MechMK1
2019-09-03 13:47:16 UTC
view on stackexchange narkive permalink

Parce que l'utilisation de variables globales vous pose un tas de problèmes, et pas vraiment d'avantages.

Les globaux rendent votre code difficile à tester

Bien qu'il ne soit pas directement lié à la sécurité, les tests unitaires sont vitaux pour le développement. Et pour tester correctement quelque chose, vous devez être en mesure de contrôler le contexte exact dans lequel le code est exécuté. Regardez les deux morceaux de code:

Avec Globals

  public Money CalculateExpenses (int departmentId) {Department department = (from d in global_db .Departments où d.Id = departmentId sélectionnez d) .Single (); return (from ex in department.Expenses select ex) .Sum ();}  

Sans Globals

  Public Money CalculateExpenses (int departmentId, Database database) {Department department = (from d dans database.Departments where d.Id = departmentId select d) .Single (); return (from ex in department.Expenses select ex) .Sum ();}  

Vous pourriez dire que le code semble presque identique, sauf d'où proviennent les données. Vous pourriez même penser que le code avec Globals est "plus propre", car vous n'avez pas à passer la base de données à chaque fois.

Jusqu'à ce que vous ayez à écrire un test unitaire. Parce que vous devrez alors insérer une logique pour ne pas vous connecter à la base de données de production, mais plutôt à une base de données locale, peut-être spécifique au test. Maintenant, le code non global est beaucoup mieux, car vous pouvez simplement passer la base de données que vous souhaitez utiliser au code.

En résumé: Le code sans Globals est plus facile à tester .

Globals change de comportement si vous ne changez pas le code

Si votre code contient environ 200 lignes de code, alors l'utilisation de Globals ne semble pas si mauvaise. En fait, cela peut sembler une chose parfaitement valable à faire si vous réutilisez le même morceau de code partout (par exemple, une source de données aléatoire, une journalisation, etc.)

Cependant, une fois que votre base de code se développe suffisamment, l'introduction de globals peut être absolument mortelle. Vous perdez tout simplement le contrôle sur la provenance de vos données et sur qui y a accès.

Prenons un exemple dans la langue préférée de tout le monde: PHP 5. Exemple par Eevee.

  @fopen ('http://example.com/not-existing-file', 'r');  

Que fait ce code? Vous ne le savez pas, car cela dépend du comportement global. Si PHP a été compilé avec --disable-url-fopen-wrapper , alors cela ne fonctionnera pas. Idem pour la configuration globale allow_url_fopen . Nous ne savons pas ce qu'il fera.

Le @ au début désactivera les messages d'erreur, sauf si scream.enabled est défini dans le global Config PHP. Il ne sera pas non plus imprimé si le niveau global error_reporting n'est pas défini. Où exactement il sera imprimé, s'il s'imprime, dépendra des display_errors globaux.

Donc, comme vous l'avez vu, le comportement d'une ligne inoffensive dépend de 5 variables globales différentes . Imaginez maintenant ce scénario dans une base de code avec un million de lignes, et 100 programmeurs différents, tous répartis dans différentes équipes, et vous verrez rapidement pourquoi l'utilisation de Globals est odieuse et conduit à toutes sortes de problèmes.

Imaginez aller travailler un jour et votre code se brise soudainement, même si vous ne l'avez pas touché. C'est la magie de Globals.

Il y a d'autres exemples des raisons pour lesquelles l'utilisation de Globals est mauvaise, que vous pouvez trouver dans les autres réponses.

Mister Amen
2019-09-03 13:03:07 UTC
view on stackexchange narkive permalink

Attaques par débordement de mémoire tampon

Bien qu'elles soient assez spécifiques au langage (C / C ++ viennent à l'esprit), et difficiles à réaliser, elles sont une attaque potentielle.

Computerphile a une superbe vidéo à ce sujet, que je recommande de tout cœur, mais voici une version courte des mécanismes de cette attaque et de son interaction avec les variables globales.

Un débordement de tampon se produit lorsque les données écrites dans un tampon corrompt également les valeurs de données dans les adresses mémoire adjacentes au tampon de destination en raison d'une vérification insuffisante des limites. Cela peut se produire lors de la copie de données d'un tampon vers un autre sans vérifier au préalable que les données tiennent dans le tampon de destination. ( Wikipédia)

Dans le cas des variables globales, la disposition de la mémoire de votre programme est assez statique car (dans la plupart des langues) leur segment de mémoire sera assigné au programme début. Cela donne de la cohérence à l'attaquant: il est beaucoup plus facile de cibler la zone mémoire d'une zone différente lorsque vous tirez toujours à partir du même endroit (dans le cas des globaux) que lorsque vous êtes toujours en mouvement entre les plans.

Ceci n'est pas spécifique aux variables globales, mais la possession d'informations significatives dans de telles structures facilite (à ne pas confondre avec l'activation!) ce genre d'attaques.

Attention !

Bien que les variables globales présentent potentiellement un léger risque pour la sécurité, si vous craignez les attaques par débordement de tampon, votre mécanisme de défense de référence devrait vérifier la taille d'entrée, pas refactoring du code pour se débarrasser des variables globales.

Je ne vois pas ce que cela a à voir spécifiquement avec les variables globales.Pouvez-vous s'il vous plaît élaborer?
Ces attaques ne sont pas directement causées par des variables globales en elles-mêmes, mais elles sont plus faciles à extraire avec des variables globales, dont l'emplacement mémoire est attribué au démarrage du programme, puis lorsque les variables sont plus étroites, ce qui rend leurs emplacements mémoire affectés moins prévisibles.Je suis un nouveau contributeur, donc je ne sais pas si je devrais intégrer cela dans la réponse car cela varie en fonction de la langue. Je ne veux pas non plus donner à qui que ce soit l'idée que la meilleure façon de protéger une application contre une attaque par débordement de tampon est une portée variable par opposition à la validation de la taille d'entrée.
pas besoin de résumer vos modifications dans votre message
Vous n'avez pas fait valoir votre argument en faveur du lien entre les globals et BO.
Yakk
2019-09-03 22:56:53 UTC
view on stackexchange narkive permalink

Je n'ai jamais eu de problème avec les variables globales dans Bash ou JavaScript, probablement parce que je n'ai écrit que de petits scripts pour un usage personnel sur des environnements minimalistes.

Pourquoi de nombreux programmeurs évitent d'utiliser des variables globales et y a-t-il des exemples de failles de sécurité causées par l'utilisation de variables globales?

Dans de petits projets, les variables globales sont très bien. La plupart de leurs problèmes n'apparaissent pas. Et la personnalisation de l'environnement Bash ci-dessus est en effet minuscule.

Les variables globales commencent à poser des problèmes à mesure que votre programme évolue; ce qui peut se produire de plusieurs façons, mais le cœur du problème est la quantité d ' état nécessaire pour comprendre chaque morceau de code.

Imaginez une base de code de 10 millions de lignes . Il contient 1 million de variables. Toutes sont globales.
Dans un morceau de code de 100 lignes, vous pouvez utiliser 20 variables.
Chaque fois que vous appelez une fonction, vous n'avez aucune idée de laquelle de ces 20 variables cette fonction va modifier; lorsque votre fonction démarre, vous ne savez pas d'où vient l'état de la variable.
Donc, pour comprendre ce que signifient vos 100 lignes de code, vous devez soit comprendre et tenir en tête les 10 millions de lignes de code, soit vous avez besoin une sorte de convention sur l'origine des données, quelles données peuvent et ne peuvent pas être modifiées lorsque vous appelez une fonction d'assistance, etc.

En revanche, si votre code est presque entièrement alimenté par des arguments de fonction, des variables locales et les types de retour, il vous suffit de comprendre votre fonction pour comprendre ce qu'elle fait. De plus, si cette fonction appelle une autre fonction, vous savez quelles informations vous lui transmettez et quelles informations elle renvoie.
Vous ne savez peut-être pas ce qu'il fait avec ces informations, mais vous savez ce qu'il ne fait pas .
Par exemple, il ne peut pas modifier entier x et vous en êtes certain, car vous n'avez pas passé x à la fonction, ni ne l'avez assigné à partir de sa valeur de retour!

Rendre le code plus facile à raisonner localement est un objectif très important. Vous voulez être capable de lire une fonction, de savoir ce qu'elle fait et d'identifier les bogues.

Écrire du code est beaucoup plus facile et beaucoup moins important que de créer du code clair et facile à raisonner.
Presque tout le code d'un grand projet persistant est lu des centaines de fois plus souvent qu'il n'est modifié, et il est écrit et conçu une seule fois.
À partir de cette règle, il est plus facile de raisonner localement - nous atteindre la règle "éviter l'état global".

Variable globale contre super-objet

Les variables globales qui sont lues / écrites sont un exemple d'état global. Mais il peut aussi y avoir un super-objet sur lequel tout dans votre projet a un pointeur sur lequel passer comme premier argument.

Un super-objet a toujours des avantages par rapport aux variables globales; les variables globales ont souvent des mécanismes déroutants sur la façon dont elles sont initialisées et nettoyées (je vous regarde, C / C ++), et si vous avez un super-objet avec tout votre état "global", vous pouvez instancier deux de votre super-objet et exécutez les deux en même temps dans le même processus (cela aura tendance à ne pas fonctionner, mais c'est généralement à cause d'un état global implicite que le système d'exploitation vous impose).

Chaque variable globale que vous lisez, au lieu d'un paramètre, signifie que n'importe quel bit de code , n'importe où pourrait modifier son comportement. Chaque variable globale dans laquelle vous écrivez signifie que vous modifiez le comportement de certains codes arbitrairement loin.

Et ce ne sont pas seulement les humains qui trouvent que les états mondiaux sont pénibles; si votre état est local, il devient beaucoup plus facile d'écrire des harnais de test qui «simulent» un état ou un environnement global. S'il y a (par exemple) un objet "souris" global, l'écriture d'un test unitaire qui crée une fausse souris qui prétend effectuer certains mouvements devient plus difficile, il peut même être plus difficile d'écrire une macro qui reproduit un mouvement de souris enregistré dans du code, surtout si vous avez l'intention de le faire pendant que l'interface utilisateur reste sensible à l'humain réel en utilisant une souris.

Sécurité

La sécurité est une fonction de comprendre ce que fait votre code. La sécurité, au sein d'un programme, signifie «votre code ne fait que ce qu'il est censé être autorisé à faire»; avec les variables globales, vous avez une capacité plus faible à comprendre ce que fait le code, donc moins de capacité à contrôler ce qu'il fait.

Steve Sether
2019-09-05 05:31:28 UTC
view on stackexchange narkive permalink

Du point de vue de la sécurité, le problème avec les variables globales est qu'elles peuvent créer un comportement inattendu et interrompre la localisation. L'idée plus générale derrière cela s'appelle "Action à distance" où une partie d'un programme peut avoir un effet inattendu sur une autre.

Puisque la localisation est interrompue, au lieu d'avoir à comprendre une seule partie du programme, vous, et toute personne travaillant avec le programme, devez maintenant comprendre toute partie du programme qui pourrait impliquer votre variable globale. Cela augmente considérablement la complexité de la conception et, en général, les conceptions complexes sont plus susceptibles d'être boguées, et donc non sécurisées. Comme l'a dit un jour les informaticiens Edsger Dijkstra: «Le programmeur compétent est pleinement conscient de la taille strictement limitée de son propre crâne».

Les programmes ont tendance à croître avec le temps en taille et en portée. Même si votre simple script, créé de manière isolée, ne fait plus qu'une chose sans modularité, il peut être réutilisé ailleurs dans le futur où vous avez peut-être oublié les implications désagréables des variables globales, ou pire, vous êtes parti et personne ne sait même qu'il contient des variables globales. Les variables globales sont comme laisser des trous dans le sol, ou des râteaux dans le mauvais sens prêts à être piétinés, ou des clous dans votre entrée.

Ils sont, à bien des égards, en danger imminent, et bien que parfois nécessaires devraient être traité comme tel.

juhist
2019-09-03 23:05:13 UTC
view on stackexchange narkive permalink
Pourquoi de nombreux programmeurs évitent d'utiliser des variables globales et y a-t-il des exemples de failles de sécurité causées par l'utilisation de variables globales?

Parce qu'il est plus facile de modifier du code qui n'utilise pas de variables globales pour s'exécuter dans des applications involontaires , des applications que le développeur d'origine n'avait pas prévues. Vraiment, si vous dépendez de l'état global, vous pouvez avoir au plus un de ces états dans une application sans refactorisation intensive (ce qui refactoriserait l'état global).

De telles applications involontaires pourraient inclure l'exécution du code dans environnements multi-threads.

Cependant, ce que beaucoup de gens ne réalisent pas: malloc () est global!

La même chose les gens qui se prononcent contre l'utilisation de variables globales utilisent tout le temps un état d'allocateur global.

Cela signifie que si un morceau de votre code alloue beaucoup de mémoire, malloc () demande plus mémoire du système d'exploitation, les blocs de mémoire se mélangent avec ceux alloués à partir d'autres morceaux de votre code, et lorsque le même morceau de code libère toute sa mémoire qu'il utilisait, les appels free () ne renvoyez pas la mémoire au système d'exploitation en raison de la fragmentation. Le résultat final est que votre programme finit par utiliser plus de mémoire qu'il ne le devrait.

Donc, ceux-là mêmes qui se prononcent contre l'utilisation de variables globales utilisent en fait un allocateur avec un état global.

Je me demande pourquoi aucune des normes des grandes organisations de normalisation (C89 / C99 / C11 / C18 par ISO, POSIX par IEEE) n'a défini d'allocateur qui vous permet d'avoir plusieurs états d'allocateur, c'est-à-dire des tas indépendants.

Vous augmentez un point valide avec `malloc`.Je pense que ces langues avec «malloc», par exempleC ou C ++, ne sont pas sûrs de toute façon.Toute arithmétique de pointeur, qui peut sembler authentique en surface, peut en fait contenir un bogue et provoquer un comportement indéfini dans tout le programme.Je suppose que les applications de sandboxing telles que les navigateurs utilisent en fait plusieurs tas - si ce n'est simplement en raison de plusieurs processus.
Dehbop
2019-09-04 02:28:14 UTC
view on stackexchange narkive permalink

Si à peu près tous les langages de programmation peuvent déclarer une variable globalement, accessible uniquement dans le cadre de son code d'implémentation, alors ce n'est pas un problème. Il n'y a pas beaucoup de raisons d'utiliser des variables globales.

Pourtant, ce n'est pas le cas, c'est pourquoi quand je me suis retrouvé à écrire mes projets en C & pas en C ++, où c'est naturellement pris en charge en tant que variable statique à la clause la plus externe d'une définition de classe, j'ai dû me contenter de variables globales.



Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 4.0 sous laquelle il est distribué.
Loading...