web-dev-qa-db-fra.com

Un logiciel sans exploit est-il possible?

J'ai entendu dire qu'il y aura toujours des vulnérabilités dans les codes et les logiciels. Cependant, je ne comprends pas pourquoi il n'est pas possible d'avoir un logiciel sans exploit. Si les entreprises continuent de mettre à jour leurs logiciels, il n'y aura finalement aucune vulnérabilité, non?

139
Zheer

Le logiciel est trop complexe

C'est de loin le facteur le plus important. Même si vous regardez simplement quelque chose comme une application Web, la quantité d'heures de travail mises dans la base de code est immense. Le code fonctionne avec des technologies, dont les normes sont des pages sur des pages longues, écrites il y a des décennies, et qui offrent des fonctionnalités dont la plupart des développeurs n'ont jamais entendu parler.

Combinez cela avec le fait que les logiciels modernes sont construits sur des bibliothèques, qui sont construites sur des bibliothèques, qui résument certaines bibliothèques de bas niveau basées sur certaines fonctionnalités du système d'exploitation, ce qui n'est encore qu'une enveloppe pour une autre fonction du système d'exploitation écrite dans les années 1990.

La pile technologique moderne est tout simplement trop grande pour qu'une seule personne puisse grogner complètement, même si vous excluez le côté OS des choses, ce qui conduit au point suivant:

Les connaissances se perdent avec le temps

Les injections SQL ont maintenant 20 ans. Ils sont toujours là. Comment ça? Un facteur à considérer est que les connaissances au sein d'une entreprise se perdent avec le temps. Vous pouvez avoir un ou deux développeurs seniors, qui connaissent et se soucient de la sécurité, qui s'assurent que leur code n'est pas vulnérable aux injections SQL, mais ces seniors finiront par occuper des postes différents, changer de société ou prendre leur retraite. De nouvelles personnes prendront leur place, et ils peuvent être tout aussi bons développeurs, mais ils ne connaissent pas ou ne se soucient pas de la sécurité. Par conséquent, ils peuvent ne pas connaître le problème ou s'en soucier, et donc ne pas le chercher.

On apprend aux gens dans le mauvais sens

Un autre point est que la sécurité n'est pas vraiment quelque chose dont les écoles se soucient. Je me souviens de la première leçon sur l'utilisation de SQL en Java et mon professeur a utilisé la concaténation de chaînes pour insérer des paramètres dans une requête. Je lui ai dit que ce n'était pas sûr et j'ai été crié pour avoir dérangé la leçon. Tous les élèves de cette classe ont vu que la concaténation de cordes est la voie à suivre - après tout, c'est ainsi que l'enseignant l'a fait, et l'enseignant n'enseignerait jamais rien de mal, non?

Tous ces étudiants entreraient maintenant dans le monde du développement et rédigeraient volontiers du code SQL facilement injectable, simplement parce que personne ne s'en soucie. Pourquoi personne ne s'en soucie? Parce que

Les entreprises ne sont pas intéressées par le "code parfait"

C'est une déclaration audacieuse, mais c'est vrai. Pour une entreprise, ils se soucient des investissements et des retours. Ils "investissent" le temps de leurs développeurs (ce qui coûte à l'entreprise une somme d'argent spécifique), et ils attendent en retour des fonctionnalités qu'ils peuvent vendre aux clients. Les fonctionnalités à vendre comprennent:

  • Le logiciel peut désormais fonctionner avec plus de formats de fichiers
  • Le logiciel comprend désormais des achats intégrés
  • Le logiciel est meilleur
  • Le logiciel vous fait mieux paraître
  • Le logiciel fonctionne plus rapidement
  • Le logiciel s'intègre de manière transparente dans votre flux de travail

Ce que les entreprises ne peuvent pas vous vendre, c'est l'absence de bugs. "Les logiciels ne sont pas vulnérables contre XSS" n'est pas quelque chose que vous pouvez vendre, et donc pas quelque chose dans lequel les entreprises veulent investir de l'argent. Résoudre les problèmes de sécurité, c'est un peu comme faire votre lessive - personne ne vous paie pour le faire, personne ne vous félicite pour le faire, et vous n'avez probablement pas envie de le faire de toute façon, mais vous devez quand même le faire.

Et encore un dernier point:

Vous ne pouvez pas tester l'absence de bugs

Cela signifie que vous ne pouvez jamais être certain que votre code contient des bogues. Vous ne pouvez pas prouver que certains logiciels sont sécurisés, car vous ne pouvez pas voir combien de bogues il reste. Permettez-moi de le démontrer:

function Compare(string a, string b)
{
    if (a.Length != b.Length)
    {
        // If the length is not equal, we know the strings will not be equal
        return -1;
    }
    else
    {
        for(int i = 0; i < a.Length; i++)
        {
            if(a[i] != b[i])
            {
                // If one character mismatches, the string is not equal
                return -1;
            }
        }

        // Since no characters mismatched, the strings are equal
        return 0;
    }
}

Ce code vous semble-t-il sécurisé? Vous pourriez le penser. Il renvoie 0 si les chaînes sont égales et -1 si ce n'est pas le cas. Donc quel est le problème? Le problème est que si un secret constant est utilisé pour une partie et une entrée contrôlée par l'attaquant pour l'autre, un attaquant peut mesurer le temps nécessaire à l'exécution de la fonction. Si les 3 premiers caractères correspondent, cela prendra plus de temps que si aucun caractère ne correspond.

Cela signifie qu'un attaquant peut essayer différentes entrées et mesurer le temps qu'il faudra pour terminer. Plus cela prend de temps, plus les caractères consécutifs sont identiques. Avec suffisamment de temps, un attaquant peut éventuellement découvrir quelle est la chaîne secrète. Cela s'appelle une attaque latérale .

Ce bug peut-il être corrigé? Oui bien sûr. Tout bug peut être corrigé. Mais le but de cette démonstration est de montrer que les bogues ne sont pas nécessairement clairement visibles, et les corriger nécessite que vous en soyez conscient, que vous sachiez les corriger et que vous soyez incité à le faire.

En résumé...

Je sais que c'est un long post, donc je ne vous blâme pas d'avoir sauté jusqu'à la fin. La version rapide est que l'écriture de code sans exploit est vraiment très difficile et devient exponentiellement plus difficile à mesure que votre logiciel devient plus complexe. Chaque technologie utilisée par votre logiciel, que ce soit le Web, XML ou autre, donne à votre base de code des milliers de vecteurs d'exploitation supplémentaires. De plus, votre employeur peut même ne pas se soucier de produire du code sans exploit - il se soucie des fonctionnalités qu'il peut vendre. Et enfin, pouvez-vous vraiment être sûr qu'il est gratuit? Ou attendez-vous simplement que le prochain gros exploit frappe le public?

266
MechMK1

Les réponses existantes, au moment de la rédaction de ce document, se concentraient sur les difficultés à créer du code sans bogue et pourquoi ce n'était pas possible.

Mais imaginez si c'était possible. Comme cela pourrait être délicat. Il existe un logiciel qui a valu le titre de "sans bug": le micro-noyau L4. Nous pouvons l'utiliser pour voir jusqu'où va le terrier du lapin.

seL4 est un micro-noyau. Il est unique car, en 2009, il s'est avéré n'avoir aucun bogue. Cela signifie qu'ils ont utilisé un système de preuve automatisé pour prouver mathématiquement que si le code est compilé par un compilateur conforme aux normes, le binaire résultant fera exactement ce que la documentation du langage dit qu'il fera. Cela a été renforcé plus tard pour faire assertions similaires du ARM binaire du micro-noyau:

Le code binaire de la version ARM du micro-noyau seL4 implémente correctement le comportement décrit dans sa spécification abstraite et rien de plus. De plus, la spécification et le binaire seL4 satisfont aux propriétés de sécurité classiques appelées intégrité et confidentialité. .

Impressionnant! Nous avons un logiciel non trivial qui est prouvé pour être correct. Et après?

Eh bien, les gens seL4 ne nous mentent pas. Ils soulignent immédiatement que cette preuve a des limites et énumèrent certaines de ces limites

Assemblage: le noyau seL4, comme tous les noyaux du système d'exploitation, contient du code d'assemblage, environ 340 lignes de ARM Assembly dans notre cas. Pour seL4, cela concerne principalement l'entrée et la sortie du noyau, ainsi que les accès directs au matériel. Pour preuve, nous supposons que ce code est correct.
Matériel: nous supposons que le matériel fonctionne correctement. En pratique, cela signifie que le matériel est supposé ne pas être falsifié et fonctionner conformément aux spécifications. Cela signifie également qu'il doit fonctionner dans ses conditions de fonctionnement.
Gestion du matériel: la preuve ne fait que les hypothèses les plus minimales sur le matériel sous-jacent. Il fait abstraction de la cohérence du cache, de la coloration du cache et de la gestion TLB (translation lookaside buffer). La preuve suppose que ces fonctions sont correctement implémentées dans la couche d'assemblage mentionnée ci-dessus et que le matériel fonctionne comme annoncé. La preuve suppose également que ces trois fonctions de gestion matérielle n'ont en particulier aucun effet sur le comportement du noyau. Cela est vrai s'ils sont utilisés correctement.
Code de démarrage: la preuve porte actuellement sur le fonctionnement du noyau après qu'il a été correctement chargé en mémoire et introduit dans un fichier cohérent, état initial minimal. Cela laisse de côté environ 1 200 lignes de la base de code qu'un programmeur du noyau considérerait généralement comme faisant partie du noyau.
Mémoire virtuelle: selon la norme des projets de vérification formels "normaux", la mémoire virtuelle n'a pas besoin d'être considérée comme une hypothèse de cette preuve . Cependant, le degré d'assurance est plus faible que pour les autres parties de notre preuve où nous raisonnons à partir du premier principe. Plus en détail, la mémoire virtuelle est le mécanisme matériel que le noyau utilise pour se protéger des programmes utilisateur et des programmes utilisateur les uns des autres. Cette partie est entièrement vérifiée. Cependant, la mémoire virtuelle introduit une complication, car elle peut affecter la façon dont le noyau lui-même accède à la mémoire. Notre modèle d'exécution suppose un certain comportement standard de la mémoire pendant l'exécution du noyau, et nous justifions cette hypothèse en prouvant les conditions nécessaires sur le comportement du noyau. La chose est: vous devez nous faire confiance que nous avons toutes les conditions nécessaires et que nous les avons obtenues. Notre épreuve vérifiée par machine ne nous oblige pas à être complète à ce stade. Bref, dans cette partie de la preuve, contrairement aux autres parties, il y a un potentiel d'erreur humaine.
...

La liste continue. Toutes ces mises en garde doivent être soigneusement prises en compte lors de la demande de preuve d'exactitude.

Maintenant, nous devons rendre hommage à l'équipe seL4. Une telle preuve est une incroyable déclaration de confiance. Mais cela montre où va le terrier du lapin lorsque vous commencez à vous approcher de l'idée de "sans bug". Vous n'obtenez jamais vraiment "sans bug". Vous commencez juste à considérer sérieusement des classes de bogues plus importantes.

Finalement, vous rencontrerez le problème le plus intéressant et le plus humain de tous: utilisez-vous le bon logiciel pour le travail? seL4 offre plusieurs grandes garanties. S'agit-il de ceux dont vous aviez réellement besoin? La réponse de MechMK1 souligne une attaque de synchronisation sur un certain code. La preuve de seL4 n'inclut pas explicitement la défense contre ceux-ci. Si vous êtes inquiet à propos de telles attaques temporelles, seL4 ne garantit rien à leur sujet. Vous avez utilisé le mauvais outil.

Et, si vous regardez l'histoire des exploits, elle est pleine d'équipes qui ont utilisé le mauvais outil et se sont brûlées pour cela.

†. En réponse aux commentaires: Les réponses parlent en fait d'exploiter le code libre. Cependant, je dirais qu'une preuve que le code est exempt de bogues est nécessaire pour prouver qu'il est sans exploit.

92
Cort Ammon

Vous pouvez avoir un code de haute qualité, mais il devient extrêmement coûteux de le développer. Le logiciel de la navette spatiale était développé , avec beaucoup de soin et des tests rigoureux, résultant en un logiciel très fiable - mais beaucoup plus cher qu'un script PHP PHP.

Certaines choses quotidiennes sont également très bien codées. Par exemple, la pile Linux TCP/IP est assez solide et a eu peu de problèmes de sécurité (bien que malheureusement, un récemment ) D'autres logiciels à haut risque d'attaque incluent OpenSSH, Remote Desktop, VPN endpoints. Les développeurs sont généralement conscients de l'importance de leur logiciel car ils fournissent souvent une "limite de sécurité", en particulier avec les attaques de pré-authentification, et en général ils font mieux et ont moins de problèmes de sécurité.

Malheureusement, certains logiciels clés ne sont pas aussi bien développés. Un exemple notable est OpenSSL qui est très largement utilisé, mais qui a des internes en désordre où il est facile d'introduire des failles de sécurité comme Heart Bleed. Des mesures ont été prises pour y remédier, par exemple LibreSSL.

Un effet similaire se produit dans le logiciel CMS. Par exemple, le noyau Word Press est généralement bien conçu et présente peu de problèmes. Mais les plugins sont beaucoup plus variables, et les plugins souvent obsolètes sont la façon dont ces sites sont piratés.

Les navigateurs Web sont en première ligne dans ce domaine. Des milliards d'utilisateurs d'ordinateurs de bureau dépendent de leur navigateur Web pour être sécurisés et empêcher les logiciels malveillants de leurs systèmes. Mais ils doivent également être rapides, prendre en charge toutes les dernières fonctionnalités et toujours gérer des millions de sites hérités. Donc, même si nous voulons tous que les navigateurs Web soient des limites de sécurité fiables, ils ne le sont pas actuellement.

En ce qui concerne les logiciels sur mesure - qui sont souvent des applications Web - les développeurs qui y travaillent sont généralement moins expérimentés et moins conscients de la sécurité que les développeurs d'infrastructure de base. Et les délais commerciaux les empêchent d'adopter une approche très détaillée et prudente. Mais cela peut être aidé avec des architectures qui contiennent du code critique de sécurité dans une petite zone, qui est soigneusement codé et testé. Le code non critique pour la sécurité peut être développé plus rapidement.

Tout le développement peut être aidé avec des outils de sécurité et des tests, y compris des analyseurs statiques, des fuzzers et des tests de plumes. Certains peuvent être intégrés dans un pipeline CI automatisé, et les services de sécurité plus matures le font déjà.

Nous avons donc un long chemin à parcourir, mais nous espérons certainement à l'avenir qu'il y aura beaucoup moins de bugs de sécurité. Et de nombreuses opportunités pour une technologie innovante qui nous y mène.

24
paj28

Oui...

Comme d'autres l'ont souligné, il est possible de vérifier votre code et de démontrer ainsi que votre code fonctionnera exactement comme prévu. La difficulté avec le calendrier de vérification et les modèles non déterministes (tels que les interactions de réseau) est une difficulté, pas une impossibilité. Les correctifs pour Meltdown et Spectre montrent que même les attaques de synchronisation de canal latéral peuvent être prises en compte et traitées.

La principale approche pour créer un code comme celui-ci est de traiter le code comme des mathématiques. Si vous ne pouvez pas vérifier votre code, ne le traitez pas comme exempt de bogues. Si vous le pouvez, alors vous avez ... seulement un coup sans bug.

... mais ...

Même si vous pouvez prouver que votre code est vierge, ne peut pas libérer les données sauf comme prévu, ne peut pas être mis dans un état erroné ou aberrant, etc., rappelez-vous que le code à lui seul ne vaut rien. Si un développeur écrit du code qui a une telle preuve, mais exécute ce code sur du matériel qui contient lui-même des vulnérabilités matérielles, la sécurité du logiciel devient théorique.

Envisagez une fonction simple pour récupérer certaines données chiffrées de la mémoire, les stocker dans un registre CPU, effectuer une transformation appropriée sur place sur ce registre pour déchiffrer, traiter et rechiffrer les données. Notez qu'à un moment donné, les données non chiffrées sont dans un registre. Si les opcodes disponibles pour ce matériel CPU offrent la possibilité d'un programme qui n'encombre pas ce registre CPU, fonctionnant parallèlement à votre code éprouvé, alors il y a une attaque basée sur le matériel.

Ce que cela signifie, en fin de compte, que pour avoir un tel logiciel sans exploit, vous devez d'abord prouver que vous avez du matériel sans exploit. Comme Meltdown et Spectre (parmi beaucoup d'autres) l'ont démontré, le matériel couramment disponible ne passe tout simplement pas cette marque.

Même le matériel des spécifications militaires et des spécifications spatiales échoue à cette mesure. Les gamme de processeurs LEON , qui sont utilisés dans les déploiements militaires et spatiaux, ne sont renforcés que contre bouleversements à événement unique (SEU) et transitoires à événement unique (SET) . C'est génial, mais cela signifie qu'il y a toujours la possibilité qu'un attaquant place le système dans un environnement avec suffisamment de rayonnement pour provoquer suffisamment de perturbations et de transitoires pour placer le matériel dans un état aberrant.

... et plus de mais ...

Il ne suffit donc pas de vérifier le logiciel et le matériel. Nous devons prendre en compte même les effets environnementaux lors de la vérification de notre matériel. Si nous exposons un LEON4 à suffisamment de rayonnement pour submerger le boîtier OR provoquer suffisamment de rayonnement induit dans le boîtier pour submerger le processeur, nous pouvons toujours provoquer une aberration. À ce stade, la somme du système total ( logiciel, matériel, environnement) serait incroyablement compliqué à définir complètement et correctement pour tenter une telle preuve.

... donc non, pas vraiment ...

Supposons que nous avons conçu un SGBDR que nous avons vérifié le code, que nous avons vérifié le matériel et que nous avons vérifié l'environnement. À un moment donné, nous avons finalement atteint le point faible de toute chaîne de sécurité:

Idio ... euh, utilisateurs.

Notre glorieuse base de données et notre illustre PFY font un système peu sûr. Le PFY - soyons plus charitables et accordons-leur le titre 'JrOp' ... Le JrOp accède à la base de données et ne reçoit que les données que le JrOp doit connaître et rien de plus, rien de moins. Dans un moment de brillance, seuls les JrOps peuvent rassembler, notre JrOp se penche sur un collègue et marmonne: "Avez-vous vu ce que User12358W vient de télécharger? Regardez ça!"

Voilà pour notre sécurité ...

... un dernier espoir (et le vaincre avec absurdité) ...

Disons, cependant, que nous imaginons l'avenir hypothétique où nous avons enfin compris conscience humaine . L'humanité a enfin atteint une comptabilité scientifique et technologique de tout le fonctionnement mental humain. Disons en outre que cela nous permet de mettre notre système à l'épreuve même de nos utilisateurs - les systèmes de rétroaction appropriés sont intégrés dans le système pour garantir que notre JrOp NE PENSE PAS même de révéler ce qui a été révélé au JrOp. Nous pouvons laisser la question de la méta-éthique et de la manipulation aux philosophes - en parlant de philosophes ...

Notez qu'à chaque étape, nous avons utilisé des preuves.

"Ah-hah", s'exclame le sceptique pyrrhonique avec joie. "Vous avez supposé qu'un système formel, tel que ZF/ZFC, Peano, la théorie des ensembles non naïfs, la logique propositionnelle classique, est solide. Pourquoi?"

Quelle réponse peut-on donner? Entre Godel et Tarski, nous ne pouvons même pas définir formellement la vérité (voir Godel's Incompleteness Theorum et Tarski's Undefinability Theorum ), donc même l'affirmation, "eh bien, nous la choisissons parce qu'elle semble bon d'utiliser un système en alignement avec la réalité ", au fond n'est qu'une hypothèse infondée - ce qui signifie que toute preuve que notre système est sans exploit est finalement elle-même une hypothèse.

... donc non, ça ne l'est pas.

Bien qu'il soit possible d'écrire du code sans bogue, en l'écrivant comme des preuves mathématiques, et donc d'atteindre techniquement l'objectif de haut niveau de `` code sans exploit '', cela nécessite de regarder le code dans le vide. Il y a une certaine valeur à cela - c'est un objectif qui en vaut la peine ("Mais cela suppose que ..." "La plupart des gens le font, Pyrrho"). Cependant, ne vous accordez jamais le confort de penser que vous avez déjà réussi à atteindre cet objectif - et si vous le faites, ayez l'humilité de nommer votre code "HMS Titanic".

11
LRWerewolf

Je veux répondre latéralement aux questions précédentes. Je ne crois pas qu'un logiciel sans bogue soit théoriquement impossible ou que le logiciel soit trop complexe. Nous avons d'autres systèmes complexes avec des taux d'erreur beaucoup plus faibles.

Il y a deux raisons pour lesquelles le code sans exploit ne se produira pas dans un avenir prévisible:

Performances et autres optimisations

De nombreux problèmes, y compris ceux exploitables, ne sont pas des cas où nous ne savons pas comment écrire le code correctement, c'est juste que le code correct serait plus lent. Ou utilisez plus de mémoire. Ou être plus cher à écrire. De nombreux raccourcis sont pris dans le logiciel pour augmenter la vitesse ou pour d'autres gains. Certains de ces raccourcis sont à l'origine d'exploits

Problèmes fondamentaux

Les systèmes que nous utilisons aujourd'hui pour créer des logiciels présentent des défauts fondamentaux qui conduisent à des exploits, mais ne sont pas en principe inévitables. Nos compilateurs ne sont pas reconnus pour leur sécurité. Le système de bibliothèque, en particulier l'écosystème Node (maintenant copié par composer, cargo et autres) d'intégration dynamique de centaines ou de milliers de petits paquets via des dépendances automatisées est une sécurité énorme cauchemar. Je devrais utiliser des polices de 72 points pour montrer à quel point énorme. Presque toutes nos langues contiennent des constructions fondamentalement non sécurisées (la pensée derrière Rust en illustre quelques-unes). Nos systèmes d'exploitation sont construits sur des systèmes encore plus anciens avec encore plus de défauts.

En bref: à l'heure actuelle, le mieux que nous puissions faire est essentiellement "d'essayer de ne pas gâcher" et ce n'est tout simplement pas suffisant pour un système complexe.

Conclusion

Donc en résumé, avec le monde du logiciel tel qu'il est aujourd'hui, non. Le code sans exploit est impossible avec ces outils, ces mentalités et ces environnements de développement, sauf si nous parlons de code trivial ou extrêmement autonome (le noyau L4 qui a déjà été mentionné).

Théoriquement, cependant, rien ne nous empêche de créer des logiciels à partir de petits modules, dont chacun peut être formellement prouvé être correct. Rien ne nous empêche de modéliser les relations, interactions et interfaces de ces modèles et de prouver formellement leur exactitude.

En fait, nous pourrions le faire aujourd'hui, mais sans progrès fondamentaux dans la conception de logiciels, ce code serait analysé, pas exécuté.

8
Tom

C'est possible? Oui. Mais pas pour le logiciel que vous recherchez.

"Bug/Exploit Free" signifie essentiellement qu'un programme aura une réponse sensible et sûre à n'importe quelle entrée. Cela peut inclure l'ignorance de cette entrée.

Le seul logiciel où cela peut être réalisé est de petits programmes triviaux juste au-delà d'un Hello World. Il n'y a aucun exploit à cela:

print("Hello World")

Parce que ce code ignore toutes les entrées et ne produit qu'une chaîne codée en dur.

Cependant, ce code accomplit également exactement 0 travail utile pour vous.

Dès que vous souhaitez, par exemple, vous connecter à Internet et télécharger quelque chose, vous téléchargerez des données sur lesquelles vous n'avez aucun contrôle et qui pourraient être malveillantes. Bien sûr, notre logiciel de téléchargement impose de nombreuses restrictions sur ces données pour vous défendre, mais il est impossible de se défendre contre un angle de menace que vous ne connaissez pas.

7
Gloweye

Oui, si la sécurité du système est mathématiquement prouvée. Ce n'est pas une idée nouvelle, les Trusted Computer System Evaluation Criteria , en bref "Orange Book" date de 1985.

enter image description here

En eux, le plus haut niveau de sécurité, nommé A1, est lorsque nous avons une conception vérifiée . Cela signifie qu'il est mathématiquement prouvé qu'il n'y a aucun moyen de briser le système.

Dans la pratique, prouver la justesse mathématique (y compris la sécurité) de tout logiciel est très difficile et un travail très délicat. Pour autant que je sache, aucun système informatique complet n'a une telle preuve, mais certains systèmes (au moins le noyau VM/ESA ) ont été partiellement éprouvés.

Notez également que la sécurité informatique traite de manière inhérente d'éventuelles attaques dont nous ne savons pas si elles proviennent. Par exemple, un tel modèle mathématique serait bien et fonctionnerait pour un système qui - directement ou indirectement - suppose qu'il n'y a aucun moyen d'écouter ses communications internes TCP. Ainsi, il serait éligible pour obtenir le certificat A1. Alors que dans la pratique, un tel système pourrait être facilement cassable sur un routeur compromis.

En général, les tests de correction automatisés (ou partiellement automatisés) des programmes, incl. leurs tests de sécurité, est un domaine de l'informatique en plein essor depuis quelques décennies. Il en est résulté de nombreuses publications et doctorats bien référés. Mais il est encore si loin de son large usage pratique, comme il y a 25 ans.

Oui

Je suis surpris que personne n'ait mentionné vérification formelle par son nom (bien que réponse de Cort mentionne le micro-noyau L4, qui a été formellement vérifié).

Je ne suis pas personnellement très familier avec la vérification formelle, donc je vais pointer quelques extraits pertinents de la page Wikipedia sur le sujet; veuillez vous y référer pour plus d'informations.

Dans le contexte des systèmes matériels et logiciels, la vérification formelle est l'acte de prouver ou de réfuter l'exactitude des algorithmes prévus sous-tendant un système par rapport à une certaine spécification ou propriété formelle, en utilisant des méthodes formelles de mathématiques. [1]

La vérification formelle des logiciels implique de prouver qu'un programme satisfait une spécification formelle de son comportement. [...]

La complexité croissante des conceptions augmente l'importance des techniques de vérification formelles dans l'industrie du matériel [6] [7]. À l'heure actuelle, la vérification formelle est utilisée par la plupart ou la totalité des principales sociétés de matériel informatique , [8] mais son utilisation dans l'industrie du logiciel est encore languissante.[citation requise] Cela pourrait être attribué au besoin accru dans l'industrie du matériel, où les erreurs ont une plus grande importance commerciale.[citation requise] [...]

Depuis 2011 , plusieurs systèmes d'exploitation ont été officiellement vérifiés: le micro-noyau Secure Embedded L4 de NICTA, vendu commercialement sous le nom de seL4 par OK Labs; [10] OSEK/VDX basé sur le système d'exploitation en temps réel ORIENTAIS par East China Normal University;[citation requise] Le système d'exploitation Integrity de Green Hills Software;[citation requise] et PikeOS de SYSGO. [11] [12]

En 2016, les professeurs Zhong Shao et Ronghui Gu de Yale et Columbia ont développé un protocole de vérification formel pour la blockchain appelé CertiKOS. [13] Le programme est le premier exemple de vérification formelle dans le monde de la blockchain et un exemple de vérification formelle utilisé explicitement comme programme de sécurité. [14]

Depuis 2017, une vérification formelle a été appliquée à la conception de grands réseaux informatiques [15] par le biais d'un modèle mathématique du réseau [16] et dans le cadre d'une nouvelle catégorie de technologie de réseau, la mise en réseau basée sur l'intention [17]. Les fournisseurs de logiciels de réseau qui offrent des solutions de vérification formelles comprennent Cisco [18], Forward Networks [19] [20] et Veriflow Systems. [21]

Le compilateur CompCert C est un compilateur C officiellement vérifié implémentant la majorité de l'ISO C.

6
Dan Dascalescu

En sécurité, nous aimons croire que rien ne peut être sécurisé, seulement durci.

C'est parce que peu importe combien vous essayez de mettre à jour vos logiciels et applications, Zero Day's existe. Surtout si votre logiciel mérite d'être piraté. Cela signifie que même si votre équipe d'ingénieurs en sécurité peut corriger le problème, le logiciel peut être exploité avant que la vulnérabilité ne devienne publique.

Et plus vous créez d'applications dans votre logiciel, plus les chances de Zero days sont élevées.

5
s h a a n

C'est possible, mais pas économique sans réglementation qui n'existe pas actuellement.

La réponse sur le noyau seL4 qui a fait ses preuves est très bonne en donnant un exemple de code sans bug dans le sens où il fonctionnera exactement comme décrit - et si leur description est fausse, eh bien, cela pourrait être appelé un exploit. Mais les bogues dans la description/spécification sont comparativement extrêmement rares et c'est discutable s'ils sont vraiment même des bogues.

Les limites qui sont également citées dans l'autre réponse se résument toutes à "nous nous sommes limités au noyau, parce que nous avions des ressources limitées". Tous pourraient être résolus en développant le matériel et les logiciels environnants et les logiciels clients de la même manière que le noyau seL4.

Si tout le monde faisait cela, alors écrire, disons, un site Web prouvablement correct deviendrait trivial, car tous les outils que vous utiliseriez seraient prouvablement corrects et vous n'écririez qu'un petit code de colle. Ainsi, la quantité de code qui devrait s'avérer correcte pour un petit projet serait petite. En ce moment, la quantité de code qui doit être prouvée correcte si vous voulez écrire un petit programme prouvablement correct est énorme parce que vous auriez essentiellement besoin de recommencer à zéro sans avoir aucun des outils disponibles qui ont été développés depuis le démarrage des ordinateurs .

Certaines personnes appellent aujourd'hui à des outils oppressifs comme la surveillance et la censure et des blocus commerciaux et contre-attaques en réponse à la numérisation. S'ils optaient plutôt pour l'incitation à des logiciels sécurisés, par exemple en exigeant une certaine responsabilité (également appelée responsabilité) des fabricants de logiciels et de matériel, nous n'aurions bientôt que des logiciels sécurisés. Il faudrait beaucoup moins de temps pour reconstruire notre écosystème logiciel de manière totalement sécurisée qu'il n'en a fallu pour le créer en premier lieu.

5
Nobody

Actuellement, il est très coûteux d'écrire du code sans bug suffisamment compliqué. Il est encore plus coûteux de vérifier qu'il est réellement exempt de bogues ou que le programme de vérification est exempt de bogues, ad infinitum. Je ne pense pas que quiconque disposait déjà d'une solution à l'échelle de la plupart des logiciels commerciaux.

Mais je dirais que certains programmes, qui peuvent contenir des bogues, seraient au moins exempts de vulnérabilités. Par exemple, un programme qui est censé s'exécuter dans un bac à sable parfait tel qu'un navigateur, et n'essaye pas d'interagir avec quoi que ce soit, sauf l'utilisateur, ou au moins n'a aucune promesse documentée à laquelle d'autres programmes sont censés faire confiance. S'il y a quelque chose qui ne va pas, c'est une vulnérabilité du bac à sable, et non le programme lui-même.

Nous avons des moyens de concevoir des systèmes qui n'acceptent un résultat que si plusieurs versions d'un programme conçues différemment sont d'accord. Et nous avons des moyens de rendre les parties d'un programme sans état. Nous pourrions recréer les promesses en utilisant ces méthodes. Comme un programme de sandboxing aurait une complexité limitée, je dirais que, dans un avenir lointain, il y a un certain espoir de pouvoir éventuellement écrire du code sans exploit tant que tous les algorithmes utilisés sont prouvables. Je ne sais pas si cela deviendra un jour économiquement viable.

3
user23013

La plupart des réponses se sont concentrées sur les bogues qui permettent des exploits. C'est très vrai. Pourtant, il existe une voie plus fondamentale pour les exploits.

S'il peut être programmé, il peut être piraté.

On peut dire à tout système qui peut être programmé de faire des choses stupides, même malveillantes.
La programmabilité peut prendre plusieurs formes, dont certaines ne sont pas très évidentes. Par exemple, un traitement de texte ou une feuille de calcul a une fonction macro. Cette fonctionnalité fournit des séquences à l'utilisateur. Si en plus, il existe des fonctionnalités permettant la sélection et la réitération, du coup c'est très programmable.

S'il ne peut pas être programmé, les utilisateurs demanderont plus de flexibilité.

À peu près n'importe quel package d'application complexe créera éventuellement un environnement dans lequel les utilisateurs voudront automatiser leur comportement de routine. Cette automatisation prend parfois la forme de scripts, comme Powershell ou Python, mais parfois elle passe par quelque chose comme une fonction macro avec quelques cloches et sifflets supplémentaires pour l'automatisation. Lorsque les constructeurs accueillent les utilisateurs, c'est soudain un système programmable.

2
Walter Mitty

Pensez simplement en termes de "développement" d'un bâtiment impénétrable ... et pensez à quelques scénarios et hypothèses possibles:

  • le budget est-il limité? C'est toujours le cas! Un mauvais acteur avec un budget plus important pourrait acheter des moyens d'entrer (comme acheter des outils, soudoyer des constructeurs, ...)
  • il y a toujours une échelle d'environnement au-delà de laquelle vous n'avez aucun contrôle: une région qui rougit, un météore frappant une infrastructure de sécurité cruciale, des avancées technologiques plus loin sur la ligne que vous n'aviez aucun moyen de planifier, ...

Vous pouvez laisser libre cours à votre imagination avec cet exemple.

Et acceptons maintenant le fait que les bâtiments sont souvent plus simples à défendre en tant qu'objets physiques, probablement plus simples et rarement construits à partir de composants avec des chaînes de dépendances aussi longues ou aussi difficiles à établir que les bibliothèques de logiciels tiers.

2
diginoise

Théoriquement, oui.

Bien qu'un logiciel sans exploit soit possible, il est extrêmement difficile à réaliser, si vous pouviez programmer un logiciel à programmer pour vous, techniquement, c'est possible. J'ai entendu parler de personnes tentant de créer quelque chose comme ça, bien que ce soit plus difficile qu'il n'y paraît, créer un bot qui peut programmer pour vous, est plus difficile qu'il n'y paraît. Un autre moyen d'exploiter un programme gratuitement est que si le logiciel est mathématiquement prouvé. Bien que le code créé par l'homme ne puisse pas réaliser quelque chose comme ça, d'autres types de la programmation peut être exploitée gratuitement si elle ne nécessite pas d'entrée humaine.

1
yosh

Écrire un code parfait, c'est comme construire une voiture parfaite. Nous pourrions peut-être construire une voiture parfaite, mais uniquement pour l'âge où nous sommes. À mesure que la technologie se développe, les idées se partagent et plus de cerveaux se rassemblent pour résoudre les problèmes, alors vous pourriez avoir quelque chose de bien mieux.

Vous avez raison de dire que si une entreprise continue de travailler sur un logiciel, à un moment donné, ils seront exempts de bogues. C'est vrai, mais avec le temps, différentes technologies évoluent et vous faites le choix de rester à jour avec la technologie ou simplement de suivre la même vieille base de code parfaite.

Prenons l'exemple de Facebook car ils sont un grand groupe et se concentrent sur un seul produit. Facebook utilisait la bibliothèque jquery pour toutes les choses dynamiques il y a quelques années. C'était une technologie de pointe et tout allait bien et je n'ai jamais pensé à la remplacer. Mais pour garder les utilisateurs engagés, ils devaient devenir beaucoup plus dynamiques. Alors que Facebook a grandi et a eu besoin de fonctionnalités de plus en plus dynamiques et a réalisé que jquery ne répondait pas à leurs besoins.

Parce qu'aucun autre site Web n'avait autant d'utilisateurs, aucun organisme n'a réellement compris le besoin de nouvelles bibliothèques. Ils ont donc commencé à travailler sur leur propre bibliothèque appelée React. Au fil du temps, de plus en plus de gens ont commencé à utiliser Internet à cause de Facebook et, de toute évidence, ils ont également été introduits sur d'autres sites. Maintenant, d'autres sites Web ont également commencé à avoir les problèmes auxquels Facebook était confronté, mais heureusement, ils avaient maintenant React Library pour répondre à leurs besoins au lieu d'en créer un nouveau.

Google avait un problème similaire et au lieu d'utiliser Facebook React, ils ont pensé à créer le leur pour répondre à leurs besoins spécifiques. Cela continuera et il n'y aura jamais une seule base de code parfaite.

C'est la loi de la nature chaque fois que quelque chose de plus gros arrive, ce qui pousse plus de gens à penser plus grand et à faire mieux que cela, similaire à la façon dont les personnages de plus en plus puissants continuent à venir dans Avengers.

Parce que le temps est la seule entité unique et qu'il n'y a jamais de temps illimité. Les propriétaires d'entreprise ainsi que les développeurs font des triades off. Les triades off dans le code peuvent être quelque chose comme:

  • Pour être plus optimisé/plus rapide ou pour être plus maniable?
  • Se concentrer davantage sur la sécurité ou avoir une meilleure expérience utilisateur?
  • Les nouvelles fonctionnalités devraient-elles être plus testées ou être livrées à temps?

Nous faisons ces triades tous les jours ...

1
omer Farooq

Pour des cas spécifiques (programmes), presque . En général, NON

  1. Pour des cas spécifiques:

Vous pouvez affiner à plusieurs reprises un programme donné jusqu'à ce que la plupart ou toutes les formes connues de vulnérabilités (c'est-à-dire les débordements de mémoire tampon) aient disparu, mais de nombreuses formes de vulnérabilités se produisent en dehors du code source. Par exemple, supposons que vous compiliez un programme presque ou parfait. Cela produit un objet ou un programme exécutable que vous distribuez. Dans l'ordinateur cible, il est exposé à des logiciels malveillants qui peuvent être modifiés de sorte que le code binaire, c'est-à-dire l'insertion de sauts dans un code malveillant qui, bien sûr, ne se trouve pas dans le programme d'origine.

  1. En général

Est-il possible d'avoir un programme, maintenant ou dans le futur, pouvant valider le code source de any programme de vulnérabilités?

Un peu de théorie. Être un programme sans vulnérabilité est une propriété sémantique des programmes, pas syntaxique. Une propriété syntaxique peut être formalisée (et donc, elle peut être détectée par des méthodes formelles), mais une propriété sémantique ne peut pas:

Une propriété sémantique n'est pas une propriété sémantique triviale. une propriété sémantique triviale est une propriété qui est toujours présente ou toujours absente dans tous les programmes. Une propriété sémantique bien connue des programmes est " Ce programme fonctionnera pour toujours" (le fameux Turing's problème d'arrêt ) parce que certains programmes s'exécuteront pour toujours, tandis que d'autres gagneront " t. Turin prouvé que le problème d'arrêt est indécidable , donc une méthode formelle pour tester la nature d'arrêt de tout programme ne peut pas exister.

Le théorème de Rice déclare que toutes les propriétés sémantiques non triviales des programmes sont également indécidables. En fait, la preuve est basée sur le fait que si une propriété sémantique non triviale des programmes était décidable, elle pourrait être utilisée pour résoudre le programme d'arrêt, ce qui est impossible.

Comme autre exemple de propriétés sémantiques, considérons la propriété " Ce programme est dangereux". Il s'agit bien sûr d'une propriété sémantique et, par conséquent, en raison du théorème de Rice, un programme de détection de malware formel et déterministe ne peut pas être construit; la plupart d'entre eux utilisent l'heuristique pour leurs procédures de détection.

Bien sûr, comme il est utilisé dans la détection des logiciels malveillants, vous pouvez utiliser l'heuristique, l'intelligence artificielle, l'apprentissage automatique, etc. pour approcher une méthode de recherche de vulnérabilités dans le code, mais une méthode formelle, parfaite et déterministe ne peut pas exister.

1
Laurence R. Ugalde

La première règle de test logiciel (QA):

'Il ne peut pas être confirmé que le dernier bogue a été trouvé'.

J'ai codé depuis 1980 (également ingénieur en électronique) et aucun de mon logiciel a été exploité, cela ne veut pas dire qu'il ne pouvait pas l'être, juste que personne ne l'a fait. Les systèmes bancaires (et les systèmes de type "Snowden") ont des alertes/audits à déclenchement automatique pour enregistrer les accès non autorisés (j'ai travaillé sur des systèmes similaires).

Alors, oui, exploiter un logiciel libre est possible, mais comment le quantifier/vérifier?

Enfin, recherchez les règles de la FCC (USA):

La partie 15 des règles de la FCC, qui régit les appareils sans licence, incorpore un principe fondamental de la politique du spectre des États-Unis: un appareil sans licence doit accepter les interférences de toute source et ne peut pas causer d'interférences nuisibles à tout service sous licence

Ce qui signifie que votre signal Wi-Fi est "exploitable", ce qui signifie que le logiciel qu'il contient est "exploitable".

0
Mr. de Silva