web-dev-qa-db-fra.com

Le code critique pour la sécurité doit-il être réutilisé ou réécrit?

Habituellement, en programmation, la réutilisation de code est toujours une meilleure idée que d'écrire votre propre implémentation d'un algorithme. Si une implémentation existe depuis longtemps et est toujours utilisée par de nombreux projets, elle est probablement assez bien conçue pour commencer, a reçu de nombreux tests et débogages, et peut-être le plus important est que quelqu'un d'autre est en charge de la maintenance cela signifie plus de temps pour se concentrer sur le produit logiciel spécifique que vous construisez.

Cependant, je me demandais si ce principe s'applique toujours au code critique pour la sécurité, qui effectue des tâches telles que le chiffrement et l'authentification, ou qui s'exécute avec des privilèges élevés pour une raison quelconque. Si une implémentation d'un algorithme est partagée par de nombreux systèmes logiciels, les gens sont fortement incités à le craquer, et lorsqu'un défaut y est détecté, il est probable qu'il s'agisse d'un désastre de sécurité massif. Heartbleed et Shellshock sont deux exemples récents qui me viennent à l'esprit. Et pour des exemples de sources fermées, choisissez n'importe quoi d'Adobe :)

De nombreux logiciels différents partageant une seule bibliothèque critique pour la sécurité font également de cette bibliothèque une cible de choix pour les attaquants qui souhaitent y insérer une porte dérobée. Dans un grand projet open source avec beaucoup d'activité, un commit de porte dérobée qui comporte également de nombreuses autres corrections (comme un nettoyage de style de code) en tant que leurre est peu susceptible d'être remarqué.

Compte tenu de tout cela, la réutilisation du code est-elle toujours considérée comme une bonne pratique pour le code effectuant des tâches critiques pour la sécurité? Et dans l'affirmative, quelles précautions doivent être prises pour atténuer les faiblesses susmentionnées de cette approche?

55
Hadrien G.

L'important est la maintenance . Que vous ayez réutilisé du code existant ou écrit le vôtre, vous n'obtiendrez une sécurité décente que s'il y a quelqu'un, quelque part, qui comprend le code et est capable de le maintenir à flot en ce qui concerne, par exemple, l'évolution des compilateurs et des plates-formes. Il est préférable d'avoir du code sans bogues, mais dans la pratique, vous devez vous fier à la meilleure chose suivante, à savoir la correction rapide des bogues (en particulier les bogues pouvant être exploités à des fins malveillantes, également appelés vulnérabilités) , dans un court laps de temps.

Si vous écrivez votre propre code, le travail de maintenance dépend entièrement de vos propres épaules. Et ce travail peut prendre beaucoup de temps. Par exemple, si vous décidez d'écrire et de maintenir votre propre bibliothèque SSL/TLS et de l'utiliser en production, alors vous devez comprendre toutes les particularités de la mise en œuvre cryptographique, en particulier la résistance à attaques par canal latéral , et vous devez garder un œil sur les attaques et contre-mesures publiées. Si vous avez les ressources pour cela, à la fois en temps et en compétence, alors très bien! Mais le coût de la maintenance ne doit pas être sous-estimé. La réutilisation d'une bibliothèque existante, en particulier une bibliothèque open source largement utilisée, peut être assez moins chère à long terme, car la maintenance est effectuée par d'autres personnes, et une utilisation généralisée garantit un examen externe. En bonus, vous ne pouvez pas être blâmé pour les failles de sécurité dans une bibliothèque externe si la moitié du monde les partage.

Pour résumer, la question ne concerne pas vraiment code réutilisation, mais effort de maintenance réutilisation.

(J'écris tout cela indépendamment des grandes qualités pédagogiques de l'écriture de votre propre code. Je vous encourage à faire vos propres implémentations - mais certainement pas pour les utiliser réellement dans la production. C'est pour apprendre .)

66
Thomas Pornin

Encore plus alors.

Le code de sécurité est délicat. Le code de cryptographie est carrément dur, même si vous êtes un cryptographe qualifié - et impossible à faire correctement, si vous ne l'êtes pas.

S'il y a tant de bogues critiques dans tant de grands progiciels et sociétés importants - qu'est-ce qui vous fait penser * que vous pourriez faire un meilleur travail?

* À moins bien sûr que ce soit votre domaine d'expertise spécifique, et que la fonctionnalité de sécurité soit au cœur de votre produit ...

38
AviD

Question interessante! Je voudrais y répondre plus du point de vue des probabilités que du point de vue des meilleures pratiques actuelles.

Bien que Thomas et d'autres fournissent d'excellentes réponses, je ne pense pas qu'ils touchent à la question centrale - qui est "est un code unique (ou moins utilisé) plus résilient dans la pratique que le code populaire". Notez que je n'ai délibérément pas utilisé "plus sécurisé que le code populaire". Et ce qui se résume à un cas particulier de "la sécurité par l'obscurité fonctionne-t-elle"?

Et (et je sais que ce ne sera pas une réponse populaire), je pense que lorsque nous remplaçons "sécurisé" par "résilient", la réponse n'est pas toujours généralement acceptée "jamais!

Il se trouve qu'il est probablement moins sécurisé (ce qui signifie: il est très probable que votre propre code de sécurité est plus facile/plus rapide à casser que celui populaire qui subissait de nombreuses attaques auparavant, et corrigé par des personnes plus intelligentes que vous).

Cependant, à moins que vous ne soyez un site grand/populaire, cela signifie également que vous êtes beaucoup moins intéressant pour les crackers potentiels s'ils ne peuvent pas réutiliser le code/l'effort dépensé pour vous cracker, et cet effort n'est pas trivial ( ce qui signifie que votre site ne se décomposera pas à automatisé paramètre non-validation/sondes d'injection SQL). Cela ne fonctionne évidemment pas si vous êtes ciblé spécifiquement (espionnage industriel, etc.), mais la grande majorité des attaques de nos jours semblent en fait être des sondes automatisées pour des logiciels populaires.

Donc, si la question n'est pas "qui est plus sûr", mais "qui est moins susceptible d'être craqué", la réponse pourrait en fait être "cela dépend". Voici quelques exemples:

Exemple 1: Imaginez un ordinateur Microsoft Windows 8.1 (ou tout ce qui est populaire de nos jours), sans aucune faille de sécurité connue, acheté mais jamais mis à jour, connecté à Internet. Imaginez également Windows 3.11 vieux de plusieurs décennies avec Winsock, jamais corrigé, avec des centaines de failles de sécurité connues, connectées à Internet. Les deux sont utilisés de la même manière. Ignorer à des fins de discussion sur la qualité de l'accès ... La question est, laquelle sera introduite plus tôt?

Bien qu'il soit évident que 3.11 est beaucoup moins sécurisé, il n'y a pratiquement aucun exploit dans la nature qui le cible. Il pourrait donc bien y avoir un exploit 0 jour massivement populaire pour 8.1 le frapper, avant que 3.11 ne frappe un exploit archaïque qui parvient à s'exécuter dessus.

Exemple 2: Imaginez que vous avez le dernier CMS Joomla sur un serveur Web sans exploits actuels connus, et un script Perl fait à la main faisant des choses CMS-ish, avec des bogues exploitables connus (mais aucun d'entre eux n'est suspect à l'heure actuelle) tests automatisés disponibles). Après un an, qui a plus de chances d'être exploité?

Bien que des preuves anecdotiques, dans quelques dizaines (à des centaines) de cas que j'ai eu au cours des dernières décennies, c'est dans la grande majorité des cas que des logiciels populaires ont été exploités, tandis que ceux obsolètes continuent de fonctionner à ce jour sans être dérangés.

Une autre chose à considérer:

  • si un logiciel populaire se met à jour automatiquement (ou a des administrateurs le mettant à jour TOUJOURS rapidement), alors les faiblesses de ce code populaire sont beaucoup réduites (mais pas éliminées, en raison d'exploits de 0 jour et non publiés) et ont donc un grand avantage
  • à l'inverse, si le logiciel ne recevra aucune maintenance, un logiciel non populaire (comme l'auto-écriture) pourrait en fait être moins suspect de problèmes
  • blâme - il peut souvent être avantageux d'utiliser des logiciels populaires. Si la moitié du monde est touchée, vous ne serez pas autant blâmé que si vous étiez un seul programmeur. Ceci est particulièrement important si vous travaillez avec de l'argent. Il est souvent "préférable" d'être moins sûr, mais de pouvoir rejeter la faute, que d'être plus sûr, mais d'avoir à supporter le coût vous-même lorsque l'exploit arrive.
  • travail - déjà mentionné par d'autres, les logiciels populaires se répareront dans la grande majorité des cas, vous avez juste besoin de mettre à jour - ce qui est beaucoup moins de travail que de trouver et de corriger vous-même les bugs (mais nécessite encore certains maintenance)
  • un autre avantage pour les logiciels auto-écrits est souvent la réduction de masse du code (conduisant à moins de bugs), car vous n'avez généralement pas besoin de la plupart des fonctionnalités ou de la personnalisation. Par exemple, les gens utiliseront Joomla même si tout ce dont ils ont besoin est un simple "site d'actualités de modèles" qui pourrait en pratique être accompli avec quelques dizaines de lignes de code. Même si vous, en tant que programmeur, n'êtes pas à moitié aussi performants que ceux qui travaillent sur un logiciel populaire (vous avez donc un nombre de bogues sensiblement plus élevé par ligne de code), vous pouvez souvent gagner encore par une grande marge en raison de l'ordre de grandeur ( ou peu!) moins de code à écrire/maintenir
15
Matija Nalis

La réponse est simple: ne lancez pas votre propre sécurité.

Il y a deux parties à cela. Algorithme et implémentation.

En ce qui concerne l'algorithme, créer votre propre algorithme de cryptage est horrible. Même si vous êtes versé dans le domaine de la cryptographie, vous n'êtes toujours pas en mesure de créer un nouvel algorithme. Sauf si vous avez une équipe d'experts dans le domaine qui y travaille, vous ne lancez pas votre propre algorithme. Pour revenir sur ce point, regardez certains des algorithmes récents qui ont été fissurés et comment ils ont été fissurés. Ce qui a l'air génial a des faiblesses que je n'aurais jamais imaginées.

En ce qui concerne l'implémentation, créer votre propre implémentation d'un bon algorithme n'est pas aussi horrible que créer votre propre algorithme, mais à moins que vous ne soyez un professionnel, ne le faites pas. Une erreur d'implémentation et peu importe la qualité de l'algorithme de base. Dans ce cas, la question que vous devez vous poser est de savoir si vous êtes meilleur que les nombreux experts qui ont travaillé pour créer une bibliothèque de sécurité haut de gamme.

Quoi de plus probable. Que vous pouvez rouler votre propre algorithme et implémentation sans aucune erreur ou faiblesse ou que l'algorithme et l'implémentation que vous utilisez auront une porte dérobée installée?

Si vous pouviez créer un algorithme parfait avec implémentation, le risque de porte dérobée ne serait pas un problème. Mais ce n'est pas réaliste.

Il y a aussi la question dont vous voulez expliquer à votre manager/actionnaires/ect.? Qu'il y avait une porte dérobée dans un progiciel de confiance haut de gamme qui fait tourner toute l'industrie ou que votre tentative personnelle d'améliorer la sécurité a horriblement échoué. Personnellement, je préférerais de loin expliquer que j'ai fait le choix que des professionnels de toute l'industrie ont fait et que la seule raison pour laquelle cela a échoué était un problème de niveau massif qui affecte même les sociétés multinationales.

Cela dit, je suis d'accord avec Thomas qu'essayer de le faire vous-même est une bonne expérience d'apprentissage tant qu'il ne voit jamais la lumière de la production.

12
Lawtonfogle

La sécurité n'est pas nécessairement améliorée simplement si le code se compile en instructions légèrement différentes. La sécurité c'est:

  1. Algorithme
  2. La mise en oeuvre
  3. Audit
  4. Entretien

Si vous n'écrivez pas mieux, des algorithmes plus sécurisés - qui peuvent prendre des années de recherche - et que votre code n'est pas audité et corrigé en conséquence, alors une implémentation légèrement différente est très peu susceptible de vous sécuriser.

Heartbleed, Shellshock, BEAST, POODLE et d'autres derniers problèmes majeurs SSL/TLS se sont produits en raison de problèmes inhérents au CRC et aux algorithmes auto-référentiels eux-mêmes, et au manque d'audits de code expérimentés, pas en raison de la mise en œuvre .

Si vous ne comprenez pas vraiment comment ils ont échoué, vous certainement ne devriez pas écrire votre propre code de sécurité. Vous ajouterez plus de problèmes que vous n'en résoudrez.

2
Courtney Schwartz