Je connais des personnes qui travaillent actuellement sur un projet pour l'armée américaine (données de faible niveau de sécurité, de type ressources humaines non liées au combat).
Un état initial du code de projet a été soumis à l'examen des forces armées, qui ont ensuite exécuté le programme à l'aide d'un outil d'analyse de la sécurité. Il renvoyait un rapport sur les problèmes de sécurité connus dans le code et nécessitait des modifications à implémenter avant la livraison du produit final.
L'un des éléments à résoudre est la suppression d'une partie du projet écrit en Ruby car il s'agit d'un langage dynamique.
Quelle est l’arrière-plan / la raison pour laquelle un langage dynamique ne peut pas être utilisé dans un environnement sécurisé? Est-ce que le gouvernement tarde à adopter les nouvelles technologies? Ou bien les langages dynamiques posent-ils un risque de sécurité supplémentaire par rapport aux langages statiques (ala C ++ ou Java )?
Réponses:
Un certain nombre de choses "soignées" peuvent être réalisées dans des langages dynamiques pouvant être insérées dans des parties du code qui ne sont pas immédiatement évidentes pour un autre programmeur ou auditeur quant à la fonctionnalité d'un morceau de code donné.
Considérons cette séquence dans irb (shell ruby interactif):
Qu'est-il arrivé il y a j'ai essayé d'appeler la méthode
foo
dans une constante de chaîne. Cela a échoué. J'ai ensuite ouvert la classe String et défini la méthodefoo
o return"foobar!"
, puis je l'ai appelée. Cela a fonctionné.Ceci est connu comme une classe ouverte et me donne des cauchemars chaque fois que je pense à écrire du code en ruby qui a une sorte de sécurité ou d’intégrité. Bien sûr, cela vous permet de faire des choses intéressantes assez rapidement ... mais je pourrais le faire chaque fois que quelqu'un stocke une chaîne, l'enregistre dans un fichier ou l'envoie sur le réseau. Et ce peu de redéfinition de la chaîne peut être caché n'importe où dans le code.
Beaucoup d'autres langages dynamiques ont des choses similaires qui peuvent être faites. Perl a Tie :: Scalar qui peut, en coulisse, modifier le fonctionnement d'un scalaire donné (ceci est un peu plus évident et nécessite une commande spécifique que vous pouvez voir, mais un scalaire transmis de quelque part pourrait poser problème). Si vous avez accès au livre de recettes Perl, recherchez la recette 13.15 - Créer des variables magiques avec des liens.
À cause de ces choses (et d'autres souvent de langages dynamiques), de nombreuses approches d'analyse statique de la sécurité dans le code ne fonctionnent pas. Perl et Undecidability montrent que tel est le cas et soulignent même de tels problèmes triviaux de surbrillance de la syntaxe (
whatever / 25 ; # / ; die "this dies!";
posent des problèmes, car ilswhatever
peuvent être définis pour accepter des arguments ou non lors de l'exécution, supprimant ainsi complètement un surligneur de la syntaxe ou un analyseur statique).Cela peut devenir encore plus intéressant dans Ruby avec la possibilité d'accéder à l'environnement dans lequel une fermeture a été définie (voir YouTube: Garder Ruby raisonnable de RubyConf 2011 de Joshua Ballanco). J'ai été informé de cette vidéo par un commentaire d'Ars Technica de MouseTheLuckyDog .
Considérons le code suivant:
Ce code est entièrement visible, mais la
mal
méthode pourrait être ailleurs ... et avec des classes ouvertes, bien sûr, il pourrait être redéfini ailleurs.Lancer ce code:
Dans ce code, la fermeture pouvait accéder à toutes les méthodes et autres liaisons définies dans la classe de cette portée. Il a choisi une méthode aléatoire et l'a redéfinie pour générer une exception. (voir la classe Binding en Ruby pour avoir une idée de ce à quoi cet objet a accès)
Une version plus courte qui montre la redéfinition d'une variable:
Qui, lors de l'exécution produit:
C’est plus que la classe ouverte mentionnée ci-dessus qui rend l’analyse statique impossible. Ce qui est démontré ci-dessus, c’est qu’une fermeture passée ailleurs entraîne tout l’environnement dans lequel elle a été définie. C’est ce qu’on appelle un environnement de première classe (comme lorsque vous pouvez faire circuler des fonctions, ce sont des fonctions de première classe, c'est l' environnement et toutes les liaisons disponibles à ce moment). On pourrait redéfinir toute variable définie dans le champ d'application de la fermeture.
Bon ou mauvais, se plaindre de rubis ou non (il y a des utilisations où l' on aurait veulent être en mesure d'obtenir à l'environnement d'une méthode (voir sécurité en Perl)), la question de « pourquoi serait rubis se limiter à un projet gouvernemental "est vraiment répondu dans cette vidéo liée ci-dessus.
Étant donné que:
Avec les implications de ces quatre choix de conception, il est impossible de savoir ce que fait un morceau de code.
Plus d'informations à ce sujet peuvent être lues sur le blog de Abstract Heresies . Le poste en question concerne le programme où un tel débat a eu lieu. (lié à SO: Pourquoi Scheme ne prend-il pas en charge les environnements de première classe? )
J'espère que cette section montre le danger que représentent les environnements de première classe et pourquoi il serait demandé de supprimer Ruby de la solution fournie. Non seulement Ruby est un langage dynamique (comme indiqué plus haut, d'autres langages dynamiques ont été autorisés dans d'autres projets), mais il y a des problèmes spécifiques qui rendent certains langages dynamiques encore plus difficiles à raisonner.
la source
"many approaches to static analysis of security in code doesn't work"
, elle est donc rejetée car elle ne peut pas être analysée (au moins par ce groupe). Je ne sais pas si je l’interprète correctement ou si c’est même une raison valable de le rejeter.En supposant que l'évaluation concerne uniquement la sécurité et pas seulement une analyse d'acceptation (c'est-à-dire, ils n'acceptent pas Ruby car ils ne veulent pas prendre en charge Ruby), puis:
Les outils d'analyse de la sécurité ont généralement du mal à adopter des comportements dynamiques.
Par exemple:
Exécutez n’importe quel projet .NET écrit avec des fonctionnalités modernes telles que ASP.NET MVC et Entity Framework via quelque chose comme Veracode et voyez quel type de liste de blanchisserie les faux positifs que vous recevez dans votre rapport.
Veracode répertorie même de nombreuses techniques de base au sein des bibliothèques principales .NET 4 en tant que "frameworks non supportés" en tant que non supportés ou en version bêta seulement, même si la plupart d’entre eux ont plusieurs années à ce jour.
Si vous avez affaire à une entité qui s’appuie beaucoup sur un tel outil, elle est presque obligée de considérer les personnes peu sûres si elle n’a pas l’expertise technique et les ressources nécessaires pour évaluer manuellement un projet et voir s’il est correctement écrit et rédigé. sécurise.
Dans les opérations civiles où les systèmes informatiques ne contrôlent généralement rien de dangereux ou de très coûteux, l'atténuation consiste à discuter des faux positifs et à les accepter généralement comme tels.
Dans les opérations bancaires, vous avez toujours une chance d’atténuer les effets positifs faux, mais vous allez passer plus de temps à discuter des détails de chaque élément. Cela devient rapidement prohibitif et vous commencez à utiliser des méthodes plus traditionnelles.
Dans l’armée, l’aviation, l’industrie lourde, etc., les systèmes peuvent contrôler des choses qui ont de terribles modes de défaillance, de sorte qu’ils peuvent avoir des règles très strictes concernant les langages, les compilateurs, etc.
Les organisations écrivent aussi généralement leur politique de sécurité pour le pire des cas. Ainsi, même si vous écrivez quelque chose de trivial, si vous écrivez pour une organisation qui a des systèmes non triviaux, le défaut sera généralement de le retenir. une norme supérieure à moins que quelqu'un demande une exception spécifique.
la source
Les langages dynamiques peuvent être utilisés dans les applications militaires et de défense. J'ai personnellement utilisé et livré des applications Perl et Python in DoD. J'ai également vu PHP et JavaScript utilisés et déployés. D'après mes expériences, la plupart du code non compilé que j'ai vu était constitué de scripts shell et de Perl, car les environnements requis sont approuvés et installés sur un grand nombre de systèmes cibles possibles.
Le fait que ces langues soient dynamiques n'est probablement pas le problème. Les interprètes de ces langues doivent être approuvés pour une utilisation sur les systèmes cibles. Si l'interprète n'est pas approuvé pour utilisation (ou peut-être l'est-il, mais il n'est pas déployé sur les systèmes cible), le langage ne peut pas être utilisé. L'utilisation d'un interpréteur donné (ou de toute application) sur un système sécurisé requiert un grand nombre d'obstacles de sécurité: analyse de la source, possibilité de compiler à partir de la source pour des environnements cibles, analyse supplémentaire des fichiers binaires, garantissant l'absence de conflit avec l'infrastructure existante, etc.
la source
J'ai passé un certain temps à interviewer le DOD (ministère de la Défense), pour un code de rédaction de poste pour le MMU du F-16 . Sans violer aucune non-divulgation: la MMU est l'unité informatique qui contrôle presque toutes les fonctions du F-16. Il est (évidemment) essentiel qu'aucune erreur, telle que des bogues d'exécution, ne se produisent pendant le vol. Il est également essentiel que le système effectue des opérations informatiques en temps réel.
Pour cette raison et pour d’autres raisons historiques, tout le code de ce système est écrit ou compilé dans ADA, un langage de programmation statique orienté objet .
Je déteste en citer trop, mais cela explique très bien pourquoi des langages statiques (comme ADA) sont utilisés pour des projets comme celui-ci:
la source
Le DoD et la NASA ont tous deux une longue histoire d'échecs en matière de programmation qui leur ont coûté des milliards de dollars. Les deux institutions ont accepté des processus qui devraient les protéger de la répétition des mêmes erreurs.
C'est une idée fausse: les langages dynamiques ne sont pas une nouvelle technologie, ils sont assez anciens. Le problème est que si vous aviez déjà un problème causé par un langage dynamique (par exemple, un typage faible / dynamique) et que ce problème vous coûtait beaucoup d'argent, vous pourriez accepter une politique qui vous empêcherait de refaire la même erreur - par exemple interdire l'utilisation de langages dynamiques dans les systèmes sensibles.
Les langages dynamiques "avalent" souvent les bogues et se retrouvent avec un comportement inattendu. Ceci est très dangereux dans les systèmes sensibles. Si quelque chose ne va pas, vous voulez le savoir dès que possible.
Si la sécurité est concernée, il serait nécessaire de voir le cas d'utilisation réel. Par exemple, je ne pense pas qu'une page Web Ruby on Rails serait automatiquement moins sécurisée qu'une page Web Java.
la source
J'aimerais ajouter aux réponses existantes en décrivant le SA-CORE-2014-005 de Drupal , une vulnérabilité très critique qui permet l'injection de SQL et finalement l'exécution de code arbitraire. Cela est dû au typage dynamique de PHP et aux règles de typage à l'exécution laxiste.
L'intégralité du correctif de ce problème est la suivante:
Ce code fait partie d'une couche d'abstraction SQL conçue pour empêcher l'injection SQL. Il faut une requête SQL avec des paramètres nommés et un tableau associatif qui fournit une valeur pour chaque paramètre nommé. La valeur est autorisée à être un tableau, dans des cas similaires
WHERE x IN (val1, val2, val3)
, où les trois valeurs peuvent être transmises en tant que valeur de tableau unique pour un paramètre nommé unique.La vulnérabilité se produit parce que le code suppose que
$i
in$i => $value
doit être un index entier de la valeur. Il poursuit et concatène cet "index" directement dans la requête SQL en tant que partie d'un nom de paramètre, car les entiers n'ont pas besoin d'être échappés, n'est-ce pas?Malheureusement pour Drupal, PHP ne fournit pas une telle garantie. Il est possible de passer dans un autre tableau associatif, dont les clés sont des chaînes, et cette boucle concaténera joyeusement la clé de chaîne dans la requête, telle quelle (rappelez-vous que le code pense qu'il ne peut s'agir que d'un entier).
Bien qu'il existe des moyens d'avoir une erreur similaire dans un langage de type statique, ils sont peu probables. Un bon développeur envisagerait ce qui
$i
pourrait être possible avant de le concaténer dans la requête. Avec un langage à typage statique, il est très facile de faire respecter$i
un nombre entier, et dans un code aussi sensible à la sécurité que celui-ci, cela serait certainement fait.En outre, le code vérifie en réalité si la valeur est un tableau avant d'itérer les éléments. Et ici se trouve une deuxième partie de l’échec qui active cette vulnérabilité: un tableau associatif et un tableau "normal" retournent true pour
is_array
. Bien qu'il soit également vrai qu'en C #, les dictionnaires et les tableaux le soientIEnumerable
, il est difficile de construire un code qui confondrait les clés de dictionnaire avec des indices de tableau comme celui-ci, même intentionnellement, et encore moins accidentellement.la source
Qu'une base de code soit sécurisée ou non dépend de la manière dont vous écrivez votre code, de la façon dont vous le testez et de la façon dont vous validez et surveillez votre processus de développement et de déploiement. Les langues ne sont ni sécurisées ni peu sûres, c'est comment vous codez.
La majorité des incidents de sécurité sont dus à des entrées malveillantes (injections de SQL, débordements de mémoire tampon), des virus, des rootkits et des chevaux de Troie. Aucune langue ne peut vous protéger de cela.
Donc, interdire aux classes de langues d'être "peu sûres" n'est pas une raison valable.
Je soupçonne que quelqu'un, pour quelque raison que ce soit - informé ou non - a décidé d'interdire ces langues. Au bout d'un moment, cela devint une vérité organisationnelle . C'était peut-être vrai à ce moment-là pour certains projets, mais les cultures de contrôle ne tiennent pas à changer les décisions (admettez qu'elles se sont trompées) et préfèrent plutôt les règles simples. Ils respectent les règles et les réglementations et peu importe qu’ils aient un sens ou non, c’est la sécurité perçue qui compte.
Cela se produit tout le temps dans les cultures de contrôle. Je le vois plus ou moins quotidiennement. Cela n'a aucun sens, mais c'est comme ça que ça se passe. Si vous souhaitez en savoir plus sur ce sujet très pertinent, je vous recommande le livre de Schneider " L'alternative de la réingénierie ". Voici un diagramme de culture de Michael Sahoto / Agilitrix , basé sur le livre de Schneider:
la source
Autant que je sache, la politique officielle du ministère de la Défense n'interdit généralement pas les langages dynamiques.
Les normes relatives aux logiciels développés ou achetés par le DoD sont promulguées par la Defense Information Systems Agency (DISA). Leur Guide de mise en œuvre technique (STIG) de Sécurité des applications - Sécurité des applications et sécurité du développement n'interdit aucune langue en particulier. Il ne mentionne pas Ruby, mais mentionne Perl et Python, qui sont également dynamiques. Il les mentionne dans le contexte de divers sujets (en suivant les normes de codage établies, en évitant les vulnérabilités d'injection de commande, etc.).
Ce que vous voyez probablement est un outil d’analyse trop strict (il existe plusieurs outils différents mentionnés dans le STIG, chacun pouvant avoir sa propre interprétation des règles) et / ou une interprétation trop stricte de ses résultats.
la source