Meilleures pratiques pour sécuriser votre SDLC

Le développement de logiciels est une pratique dans laquelle de plus en plus de personnes dans le monde sont engagées. Il existe à la fois des entreprises et des particuliers qui créent des logiciels, certains propriétaires, d'autres gratuits ou open source, et d'autres encore sont une fusion des deux. Étant donné que les menaces à la sécurité des utilisateurs ou de leurs logiciels ne se matérialisent pas dès que quelque chose est déclaré terminé et expédié en production, il semble que ce soit le bon moment pour parler de pratiques de sécurité qui aideraient à gérer les risques de sécurité qui pourraient s'infiltrer dans votre logiciel pendant le processus de développement. Il existe plusieurs frameworks SSDLC (Secure Software Development Life Cycle), notamment ceux de OWASP, CISA ainsi que NIST (SSDF). Dans cet article, nous emprunterons un peu à chacun d'entre eux pour mettre en évidence quelques pratiques visant à vous aider à gérer le risque inhérent au développement logiciel. Ne vivez pas avec un faux sentiment de sécurité en pensant que cela ne peut pas vous arriver. Le rapport de mi-année 2023 de Check Point sur la cybersécurité révèle une augmentation de 8 % des cyberattaques mondiales sur 2022, et la tendance ne semble pas s’inverser. 

Quel est le cycle de vie du développement logiciel

Les développeurs de logiciels visent à créer des logiciels rapidement, précisément et en toute sécurité. Bien sûr, on ne peut pas toujours obtenir les trois. Au fil du temps, le processus de développement s’est divisé en plusieurs phases distinctes pouvant s’adapter à tout développement logiciel. Ces phases peuvent être décomposées comme suit : 

  1. Analyse des besoins – qu’allons-nous construire et pourquoi
  2. Préproduction – comment nous allons le construire en termes généraux
  3. Conception de logiciels – comment nous allons le construire en termes spécifiques tels que la conception architecturale
  4. Développement de logiciels – écrire et compiler le logiciel
  5. Essais – assurez-vous que cela fonctionne comme prévu
  6. Déploiement – l’expédier ou le publier pour que l’utilisateur final puisse l’utiliser

Il existe quelques autres versions de ce cycle mais dans l’ensemble elles sont très similaires. Il est important de se rappeler que le cycle n'est pas une chose ponctuelle : il ne se termine généralement pas une fois que vous l'avez expédié au client ou que vous l'avez publié dans le cloud. Il y a presque toujours des problèmes que vous devez résoudre et qui peuvent nécessiter une refonte (retour à la case départ), des bogues que vous devez corriger, des fonctionnalités que vous souhaitez ajouter, etc. Vous pouvez également vous retrouver à travailler sur quelques étapes en parallèle ou à vous arrêter à mi-étape pour revenir en arrière. Étant donné qu'aucune des étapes n'est intrinsèquement centrée sur la sécurité, la sécurité doit constamment rattraper le processus de développement et, dans le contexte de développement effréné d'aujourd'hui, cela ne suffit pas.

L'importance de sécuriser votre SDLC

Le développement de logiciels sécurisés vise à inclure des considérations de sécurité à toutes les étapes du processus, sans considérer la sécurité comme un module complémentaire au processus. De cette manière, la sécurité doit toujours être une considération, quelle que soit la phase du processus dans laquelle vous êtes engagé : réfléchir aux exigences du projet, planifier l'architecture, prendre en compte les éléments de base et l'infrastructure requis et s'asseoir pour développer le code. Cette approche est parfois appelée sécurité majuscule à gauche approche.

Ici, le décalage vers la gauche fait référence à la répartition des problèmes de sécurité tout au long du processus de développement et à l'implication des développeurs dans la conception, la mise en œuvre et les tests de sécurité.

Il peut être intimidant pour les développeurs qui n’ont jamais vraiment réfléchi aux problèmes de sécurité de devoir soudainement y faire face. Il est nettement plus facile à gérer si les exigences sont divisées en plusieurs bonnes pratiques bien définies. Vous pouvez y penser comme si vous aviez acheté un nouvel IDE.

Plus les exigences sont bien définies et plus vous pouvez utiliser d’outils automatisés et complets, plus les tâches deviendront faciles.

Diagramme

Meilleures pratiques de sécurité SDLC

Voici quelques bonnes pratiques pour vous aider à sécuriser votre processus de développement, sans ordre particulier :

Formation – De nombreux développeurs ne se sentiraient pas à la hauteur de la tâche consistant à appliquer des considérations de sécurité et à effectuer des tests au code qu'ils écrivent. La majorité des développeurs sont conscients que laisser des données d'entrée corrompues dans votre backend peut entraîner l'activation de code à distance, un peu comme les fameuses « tables de dépôt ». Cependant, moins de personnes seraient familiarisées avec les tests de dépassement de tampon ou l'analyse des vulnérabilités pour les dépendances tertiaires (ou supplémentaires). Les développeurs peuvent combler ces lacunes en matière de connaissances grâce à la formation. Les développeurs sont mieux équipés pour intégrer les problèmes de sécurité dans leur codage et leurs tests quotidiens lorsqu’ils ont une compréhension plus approfondie des défis de sécurité et des vulnérabilités potentielles. Il est également beaucoup plus logique que le développeur qui a écrit le code et qui connaît parfaitement sa fonction prenne en compte ses failles de sécurité et planifie les tests en conséquence.

Balayage – Vous pouvez utiliser de nombreux types d’analyse pour rendre votre code globalement plus sécurisé. Les analyses statiques, dynamiques et interactives en sont quelques-unes. L'analyse statique recherche des défauts de codage évidents ou d'éventuelles vulnérabilités de sécurité dans le code source. Il peut être utilisé pour rechercher des vulnérabilités potentielles, des pratiques de code non sécurisées et des violations des normes de codage. Il ne prend pas en compte les événements d'exécution car il examine uniquement la syntaxe du code. L'analyse dynamique recherche les failles de sécurité, les défauts de codage et autres problèmes dans l'application pendant son exécution. Il peut être utilisé pour identifier les fuites de mémoire, les opérations médiocres et éventuellement les entrées ou processus instables. Gardez à l’esprit que puisque ce type de test est effectué à un moment donné en utilisant des entrées spécifiques, la qualité des tests dépend entièrement des personnes qui les ont conçus. L’objectif est de trouver les problèmes avant vos utilisateurs. L'analyse interactive examine l'application pour détecter d'éventuelles failles de sécurité et autres problèmes de rupture. Il peut rechercher d'éventuelles vulnérabilités, des problèmes d'utilisabilité et des problèmes avec l'interface utilisateur. Plus vous utilisez des outils d’analyse complets, mieux vous êtes protégé, mais le compromis réside bien sûr dans la vitesse de développement. Chaque application étant unique, à vous de trouver l'équilibre entre la bonne quantité de numérisation et la vitesse de développement souhaitée. De plus, nous vous recommandons de créer un SBOM complet de votre application et d'appliquer également diverses analyses et rapports à cette source de données. Avoir un héritage SBOM de votre application est un bon moyen de conserver des informations très détaillées sur les composants et les packages qui pourraient être inestimables pour de nombreuses raisons de sécurité. 

Revues de code – L'examen du code source pour détecter les failles de sécurité, les erreurs de codage et autres défauts logiciels avant qu'il ne soit combiné avec la branche de développement active est appelé révision du code. En règle générale, cet examen est effectué par un développeur possédant une plus grande expertise que celui qui a rédigé le code. De tels examens peuvent contribuer à garantir que le code est bien écrit et que l'application est sûre. De plus, ils prennent en charge le maintien d’une norme unique et de conventions de codage (telles que les noms de fonctions et de variables) dans l’ensemble de la base de code.

Autoriser l'intégration du code dans la branche principale après qu'au moins deux paires d'yeux l'ont examiné est considéré comme une bonne pratique. Le développeur qui a écrit le code est, bien entendu, la première paire d’yeux. Il peut être avantageux, même pour les ingénieurs hautement qualifiés, tels que les chefs d'équipe, de demander à quelqu'un d'autre d'évaluer leur code. À tout le moins, cela garantit que plus d’une personne connaît chaque section du code. Gardez à l’esprit qu’en période de grand stress ou lorsque le temps est compté, les gens peuvent envisager de renoncer à cet élément. Si possible, envisagez d'ajouter cette règle en tant qu'élément codé en dur de votre CI/CD afin qu'elle ne puisse pas être contournée.

Essais – Nous n'avons pas besoin de vous dire à quel point il est important de tester votre code pour découvrir les failles de sécurité avant qu'elles ne deviennent un problème. La majorité des projets de code sont complexes et interconnectés. Il est donc impossible de prévoir comment une seule petite lacune peut éventuellement avoir un impact sur la sécurité de l'ensemble de la base de code.

Lors de l'écriture de tests automatisés, tenez compte de la fonctionnalité du code récemment produit ainsi que de toute interaction back-end et front-end significative avec d'autres parties de la base de code.

Les vulnérabilités telles que l'injection SQL, les scripts intersites, le stockage de données non sécurisé et l'allocation de mémoire inadéquate (pouvant entraîner des débordements de mémoire tampon) sont des exemples de problèmes de sécurité généralement résolus lors des tests. Les tests doivent résoudre les fuites de mémoire, les performances lentes ou peu fiables et la convivialité. Les tests doivent être automatiques et intégrés au pipeline CI/CD afin qu'aucune nouvelle version ou mise à jour ne puisse être publiée sans subir à la fois des tests unitaires et d'intégration. 

Tests d'intrusion indépendants – Personne ne peut penser à tout et en tant que développeurs, nous développons parfois des angles morts par rapport au code que nous avons écrit. Semblables à la révision du code, les tests d'intrusion indépendants permettent une nouvelle approche et un autre regard pour examiner de manière critique ce que nous avons fait et les précautions que nous avons prises pour sécuriser notre application et nos utilisateurs. De tels tests sont recommandés au moins une fois par an et doivent intégrer une évaluation de l'infrastructure ainsi que des vulnérabilités des applications.

Utilisez l’open source en toute sécurité – Presque tous les logiciels en développement aujourd’hui incluent plus ou moins des logiciels open source. Les composants open source sont parmi les principales causes de vulnérabilités importées dans votre application, soit directement, soit via des dépendances transitoires. De plus, ce ne sont pas seulement les bibliothèques que vous utilisez qui peuvent vous mettre en danger, mais également le fait de ne pas mettre à jour les anciennes bibliothèques ou de ne pas se tenir à jour avec les dernières CVE publiées qui pourraient vous affecter. Nous vous recommandons de créer une liste de packages open source approuvés pour une utilisation par l'organisation et de la vérifier et de la mettre à jour en permanence. Empêcher les développeurs d'ajouter n'importe quel package qu'ils souhaitent, même à titre de test, pourrait aider à réduire le nombre de vulnérabilités auxquelles vous devez faire face. 

Assurez-vous que les vulnérabilités ne se transforment pas en exploits – Il n’existe quasiment aucune base de code dépourvue de vulnérabilités. Toute analyse décente en révélerait des centaines, voire des milliers. Il est impossible de tous les éliminer. Il est également important de rappeler que les vulnérabilités ne sont pas des exploits. Assurez-vous de disposer d'un processus de filtrage pour vous assurer que toute vulnérabilité que vous découvrez n'est pas une menace exploitable et gardez cette liste constamment à jour. De cette façon, vous pouvez rassurer les tiers ou utilisateurs préoccupés par le dernier CVE en leur disant qu'il n'a absolument aucun impact sur votre application.

La sécurité commence par votre état d'esprit

Il existe probablement autant de façons différentes de développer des logiciels qu’il y a de développeurs, de frameworks et de langages de codage. Autrement dit, il n'est pas facile de trouver les meilleures pratiques pour sécuriser votre processus de développement qui soient pertinentes quel que soit le langage, le domaine ou l'EDI que vous utilisez. Au-delà d'une pléthore d'outils, certains propriétaires et d'autres gratuits, tous réclamant votre attention comme « le prochain outil de sécurité irremplaçable », l'outil de sécurité le plus important que vous puissiez utiliser est votre état d'esprit.

Pensez à vos choix de conception, d’architecture et de stockage. Avez-vous envisagé l’option d’une croissance exponentielle de votre base d’utilisateurs ? Avez-vous correctement segmenté les privilèges d'accès pour les différentes parties de votre base de code et de votre infrastructure ? Avez-vous envisagé à la fois une attaque ciblée contre vos données ou vos secrets et une attaque « indirecte » de la chaîne d'approvisionnement logicielle ?   

Toutes ces questions et bien d'autres doivent être prises en compte avant même de vous asseoir pour planifier votre application et elles doivent être régulièrement réinspectées à mesure que la base de code et l'application grandissent et évoluent. 

Il est considéré comme un axiome que la partie la plus vulnérable de tout logiciel est l'humain qui l'exécute (ou l'écrit). Ne laissez pas votre application, logiciel ou bibliothèque de codes participer aux statistiques croissantes d'une nouvelle vague de cyberattaques. Avec une planification, des outils et une automatisation appropriés, vous pouvez trouver le bon équilibre entre la gestion des cyber-risques, la sécurisation de votre cycle de vie de développement et la production d'un code bien documenté, complet et efficace.