Exporter (0) Imprimer
Développer tout

Instructions de conception pour les applications Web sécurisées

Dernière mise à jour le 31 août 2004
Sur cette page

Dans ce module Dans ce module
Objectifs Objectifs
S'applique à S'applique à
Aspects à considérer pour l'architecture et la conception des applications Web Aspects à considérer pour l'architecture et la conception des applications Web
Remarques relatives au déploiement Remarques relatives au déploiement
Validation des entrées Validation des entrées
Authentification Authentification
Autorisation Autorisation
Gestion de la configuration Gestion de la configuration
Données sensibles Données sensibles
Gestion des sessions Gestion des sessions
Cryptographie Cryptographie
Manipulation des paramètres Manipulation des paramètres
Gestion des exceptions Gestion des exceptions
Audit et journalisation Audit et journalisation
Résumé des conseils de conception Résumé des conseils de conception
Résumé Résumé
Informations complémentaires Informations complémentaires

Dans ce module

Les applications Web présentent un ensemble complexe de problèmes de sécurité pour les architectes, les concepteurs et les développeurs. Les applications Web les plus sécurisées et les plus résistantes au piratage sont celles qui ont été développées de bout en bout avec le souci de garantir la sécurité.

Vos pratiques en matière d'architecture et de conception doivent être avisées, et vous devez intégrer les aspects liés au déploiement et les stratégies de sécurité de l'entreprise dès les premières phases de la conception. Si vous ne respectez pas ces conditions, les applications qui en résulteront ne pourront être déployées dans une infrastructure existante sans en compromettre la sécurité.

Ce module présente une série d'instructions relatives à l'architecture et à la conception sécurisées. Ces instructions sont organisées par catégorie de vulnérabilité des applications courantes. Il s'agit des principaux domaines de sécurité des applications et des domaines dans lesquels on rencontre le plus fréquemment des erreurs.

Objectifs

Ce module vous permettra :

  • d'identifier les principaux problèmes en termes d'architecture et de conception pour les applications Web sécurisées ;

  • de prendre en considération les principaux problèmes de déploiement lors de la conception ;

  • de concevoir des stratégies visant à améliorer la validation des entrées de vos applications Web ;

  • de concevoir des mécanismes sécurisés d'authentification et de gestion des sessions ;

  • de choisir un modèle d'autorisation approprié ;

  • d'appliquer des pratiques efficaces de gestion des comptes et de protéger les sessions utilisateur ;

  • d'utiliser la cryptographie afin d'assurer la confidentialité, la non-répudiation, l'inviolabilité et l'authentification ;

  • d'empêcher la manipulation des paramètres ;

  • de concevoir des stratégies d'audit et de journalisation.

S'applique à

Bien qu'elles soient contenues dans un ouvrage relatif à la sécurité ASP.NET, les informations de ce module s'adressent à tous ceux qui sont concernés par le développement d'applications Web sécurisées.

Aspects à considérer pour l'architecture et la conception des applications Web

Les concepteurs et développeurs des applications Web doivent faire face à un grand nombre de difficultés. La nature sans état de HTTP signifie que le suivi de session par utilisateur relève désormais de la responsabilité de l'application. Au préalable, l'application doit être capable d'identifier l'utilisateur en faisant appel à une forme ou une autre d'authentification. Sachant que toutes les décisions d'autorisation ultérieures sont basées sur l'identité de l'utilisateur, il est essentiel que le processus d'authentification soit sécurisé et que le mécanisme de gestion de session utilisé pour suivre les utilisateurs authentifiés bénéficie du même niveau de protection. La conception de mécanismes d'authentification et de gestion de session ne constitue qu'une partie des difficultés auxquelles les concepteurs et développeurs des applications Web sont confrontés. D'autres difficultés apparaissent du fait que les données d'entrée et de sortie sont transmises sur des réseaux publics. La prévention de la manipulation des paramètres et la divulgation des données sensibles constituent d'autres problèmes majeurs.

Certains des principaux problèmes devant être résolus en ayant recours à des pratiques de conception sécurisée sont illustrés dans la figure 4.1.

Problèmes de conception des applications Web

Figure 4.1
Problèmes de conception des applications Web

Les instructions de conception de ce module sont organisées par catégorie de vulnérabilité de l'application. L'expérience montre qu'une conception médiocre, en particulier dans ces domaines, se traduit par des failles de sécurité. Le tableau 4.1 énumère les catégories de vulnérabilité, et pour chacune d'entre elle, met en évidence les problèmes potentiels pouvant découler d'une mauvaise conception.

Tableau 4.1 : Vulnérabilités des applications Web et problèmes potentiels dus à une conception médiocre

Catégorie de vulnérabilité

Problème potentiel dû à une conception médiocre

Validation des entrées

Attaques réalisées en insérant des chaînes malveillantes dans des chaînes de requête, des champs de formulaires, des cookies et des en-têtes HTTP. Il peut s'agir d'attaques d'exécution de commande, de script inter-site (XSS), d'injection SQL et de dépassement de la capacité de la mémoire tampon.

Authentification

Usurpation d'identité, décodage de mot de passe, élévation des privilèges et accès non autorisé.

Autorisation

Accès à des données confidentielles ou restreintes, falsification et exécution d'opérations non autorisées.

Gestion de la configuration

Accès non autorisé aux interfaces d'administration, capacité à mettre à jour les données de configuration et accès non autorisé aux comptes utilisateurs et aux profils de compte.

Données sensibles

Divulgation d'informations confidentielles et falsification des données.

Gestion des sessions

Capture des identificateurs de session se traduisant par le piratage de session et l'usurpation d'identité.

Cryptographie

Accès à des données confidentielles ou à des informations d'identification de compte, ou les deux.

Manipulation des paramètres

Attaques de pénétration de répertoire, exécution de commande et contournement des mécanismes de contrôle d'accès (entre autres), se traduisant par la divulgation d'informations, l'élévation des privilèges et le refus de service.

Gestion des exceptions

Refus de service et divulgation d'informations sensibles de niveau système.

Audit et journalisation

Absence de détection des signes d'intrusion, incapacité à authentifier les actions d'un utilisateur et difficultés à diagnostiquer les problèmes.

Remarques relatives au déploiement

Au cours de la phase de conception de l'application, vérifiez les stratégies et procédures de sécurité de l'entreprise, ainsi que l'infrastructure dans laquelle votre application doit être déployée. Il est fréquent que l'environnement cible soit rigide, c'est pourquoi la conception de votre application doit refléter ces restrictions. Des compromis de conception sont parfois nécessaires, par exemple du fait de restrictions relatives au protocole ou au port, ou à des topologies spécifiques de déploiement. Identifiez de façon précoce les contraintes dans la phase de conception afin d'éviter des surprises ultérieures et impliquez les membres des équipes réseau et infrastructure pour qu'ils vous aident dans ce sens.

La figure 4.2 montre les divers aspects de déploiement devant être pris en considération lors de la phase de conception.

Remarques relatives au déploiement

Figure 4.2
Remarques relatives au déploiement

Stratégies de sécurité et procédures

La stratégie de sécurité détermine ce que vos applications peuvent faire et la marge de manœuvre des utilisateurs d'une application. Qui plus est, elle définit les restrictions permettant de déterminer ce que les applications et les utilisateurs n'ont pas le droit de faire. Identifiez et respectez l'infrastructure définie par la stratégie de sécurité de votre entreprise lors de la conception de vos applications ; si cette stratégie n'était pas respectée, elle risquerait d'empêcher le déploiement de l'application.

Infrastructure du réseau

Veillez à bien comprendre la structure du réseau de votre environnement cible, ainsi que les exigences de sécurité de base du réseau en termes de règles de filtrage, de restrictions de ports, de protocoles pris en charge, etc.

Identifiez de quelle manière les pare-feu et stratégies associées peuvent affecter la conception et le déploiement de votre application. Il peut exister des pare-feu séparant les applications accessibles via Internet du réseau interne. Il peut exister d'autres pare-feu devant la base de données. Ceci peut avoir une incidence sur les ports de communication possibles et, par conséquent, sur les options d'authentification depuis le serveur Web vers les serveurs distants d'application et de base de données. Par exemple, l'authentification Windows nécessite des ports supplémentaires.

En phase de conception, prenez en considération les protocoles, les ports et les services autorisés à accéder à des ressources internes à partir des serveurs Web dans le réseau de périmètre. Identifiez également les protocoles et les ports que requiert la conception de l'application et analysez les menaces potentielles liées à l'ouverture de nouveaux ports ou à l'utilisation de nouveaux protocoles.

Communiquez et enregistrez toutes les hypothèses concernant la sécurité des couches réseau et application, ainsi que les composants chargés de gérer chaque élément. Ceci évite d'oublier des contrôles de sécurité si, par exemple, l'équipe de développement suppose que l'équipe réseau s'est chargée d'un problème et que cette dernière en fait autant. Soyez attentif aux défenses que le réseau est censé fournir à votre application. Envisagez les implications d'une modification de la configuration du réseau. Pouvez-vous mesurer la baisse de sécurité consécutive à la mise en œuvre d'une modification particulière du réseau ?

Topologies de déploiement

La topologie de déploiement de votre application et le fait de disposer ou non d'une couche d'application distante sont des éléments clés qui doivent être intégrés à votre conception. Si vous disposez d'une couche d'application distante, vous devez considérer de quelle manière sécuriser le réseau entre les serveurs pour résoudre la menace d'écoute clandestine du réseau et garantir la confidentialité et l'intégrité des données sensibles.

Prenez également en considération le flux des identités et identifiez les comptes qui seront utilisés pour l'authentification du réseau lorsque votre application se connecte à des serveurs distants. Une approche courante consiste à utiliser le compte de processus le moins privilégié et à créer un compte en double (miroir) sur le serveur distant avec le même mot de passe. Vous pouvez également utiliser un compte de processus de domaine, qui facilite l'administration mais est plus délicat à sécuriser du fait de la difficulté de limiter son utilisation sur l'ensemble du réseau. Un pare-feu intermédiaire ou des domaines séparés sans relations de confiance font souvent de l'approche par compte local la seule option viable.

Intranet, extranet et Internet

Les scénarios d'application Intranet, extranet et Internet présentent chacun leurs propres difficultés. Les questions que vous devez prendre en compte sont les suivantes : comment allez-vous faire circuler l'identité de l'appelant à travers plusieurs niveaux d'application vers les ressources d'arrière-guichet ? Où allez-vous effectuer l'authentification ? Pouvez-vous faire confiance à l'authentification frontale, puis utiliser une connexion approuvée pour accéder aux ressources principales ? Dans les scénarios extranet, vous devez également décider si vous pouvez faire confiance aux comptes des partenaires.

Pour plus d'informations sur ces questions et sur d'autres problèmes relatifs à certains scénarios, consultez les sections « Intranet Security », « Extranet Security » et « Internet Security » de « Building Secure ASP.NET Web Applications: Authentication, Authorization, and Secure Communication » à l'adresse http://msdn.microsoft.com/library/en-us/dnnetsec/html/secnetlpMSDN.asp.

Validation des entrées

La validation des entrées est un problème délicat et la responsabilité principale de sa solution repose sur les épaules des développeurs d'applications. Néanmoins, une validation correcte des entrées est l'une des meilleures mesures de défense contre les attaques actuelles visant les applications. Elle constitue une contre-mesure efficace pour empêcher les attaques de type XSS, injection SQL, dépassement de la capacité de la mémoire tampon, et autres attaques par introduction d'informations dans l'application.

La validation des entrées est délicate du fait qu'il n'existe pas de réponse unique vis-à-vis de ce qui constitue une saisie valide à travers des applications, voir au sein d'une même application. De même, il n'existe pas de définition unique de ce qu'est une entrée malveillante. Pour ne rien simplifier, l'utilisation que fait votre application de ces entrées influe sur le risque lié au détournement. Par exemple, stockez-vous des données à l'intention d'autres applications ou votre application consomme-t-elle les entrées provenant de sources de données créées par d'autres applications ?

Les pratiques suivantes visent à améliorer la validation des entrées de vos applications Web :

  • Partir du principe que toute entrée de données est malveillante.

  • Centraliser votre approche.

  • Ne pas faire confiance à la validation côté client.

  • Être prudent vis-à-vis des problèmes de canonisation.

  • Contraindre, rejeter et assainir vos entrées.

Partir du principe que toute entrée de données est malveillante

La validation des entrées repose sur la supposition fondamentale que toute entrée est malveillante jusqu'à preuve du contraire. Que les entrées émanent d'un service, d'un partage de fichier, d'un utilisateur ou d'une base de données, validez-les si la source se trouve hors de votre frontière de sécurité. Par exemple, si vous appelez un service Web externe qui retourne des chaînes, comment pouvez-vous savoir si des commandes malveillantes ne s'y trouvent pas ? De plus, si plusieurs applications écrivent dans une base de données partagée, lorsque vous lisez les données, comment savoir si elles sont saines ?

Centraliser votre approche

Faites de votre stratégie de validation de saisie un élément central de votre conception d'application. Envisagez une approche de validation centralisée, par exemple en utilisant un code commun de validation et de filtrage dans des bibliothèques partagées. Ceci garantit que les règles de validation sont appliquées en permanence. Ceci réduit en outre les efforts de développement et favorise la maintenance future.

Dans un grand nombre de cas, des champs individuels nécessitent une validation spécifique, par exemple avec des expressions régulières spécialement développées. Cependant, il est fréquent que l'on puisse prendre en compte des routines courantes pour valider des champs utilisés régulièrement tels que les adresses électroniques, les titres, les noms, les adresses postales contenant des codes postaux, etc. Cette approche est illustrée dans la figure 4.3.

Une approche centralisée de la validation des entrées

Figure 4.3
Une approche centralisée de la validation des entrées

Ne pas faire confiance à la validation côté client

Le code côté serveur doit effectuer sa propre validation. Que se passe-t-il si un attaquant contourne votre client ou neutralise vos routines de script côté client, par exemple, en désactivant JavaScript ? Utilisez la validation côté client pour aider à réduire le nombre de boucles vers le serveur mais ne vous basez pas dessus pour la sécurité. Ceci est un exemple de défense renforcée.

Être prudent vis-à-vis des problèmes de canonisation

Les données de forme canonique se présentent dans leur forme la plus standard ou la plus simple. La canonisation est le processus de conversion des données dans leur forme canonique. Les chemins d'accès aux fichiers et les URL sont particulièrement enclins à des problèmes de canonisation et de nombreuses attaques sont le résultat direct de bogues de canonisation. Par exemple, supposons la chaîne suivante contenant un fichier et un chemin d'accès dans sa forme canonique.

c:\temp\somefile.dat

Les chaînes suivantes pourraient également représenter le même fichier.

somefile.dat
c:\temp\subdir\..\somefile.dat
c:\  temp\   somefile.dat
..\somefile.dat
c%3A%5Ctemp%5Csubdir%5C%2E%2E%5Csomefile.dat

Dans le dernier exemple, les caractères ont été saisis dans leur forme hexadécimale :

  • %3A est le caractère deux points.

  • %5C est le caractère barre oblique inverse.

  • %2E est le caractère point.

Il est généralement recommandé d'éviter de concevoir des applications acceptant des noms de fichier saisis par l'utilisateur pour éviter les problèmes de canonisation. Il est préférable d'envisager d'autres formes de conception. Par exemple, vous pouvez laisser l'application déterminer le nom du fichier pour l'utilisateur.

Si vous devez accepter la saisie de noms de fichiers, assurez-vous qu'ils sont formés de façon stricte avant de prendre des décisions de sécurité telles que l'accord ou le refus d'accès au fichier spécifié.

Pour plus d'informations concernant la gestion des noms de fichier et l'exécution des E/S de fichier de façon sécurisée, consultez les sections « E/S de fichier » du module 7, « Construction d'assemblages sécurisés », et du module 8, « Sécurité d'accès au code en pratique ».

Contraignez, rejetez et assainissez votre saisie

L'approche de prédilection en matière de validation des entrées consiste à limiter ce que vous autorisez dès le début. Il est beaucoup plus facile de valider des données de types, modèles et plages valides connus que de valider des données en recherchant des caractères réputés incorrects. Lorsque vous concevez votre application, vous savez ce qu'elle attend. La plage de données valides est généralement un ensemble fini d'éléments, dans lequel une entrée potentiellement malveillante n'a pas sa place. Néanmoins, pour assurer une défense renforcée, vous pouvez également rejeter les entrées connues comme incorrectes, puis assainir la saisie. La stratégie recommandée est illustrée dans la figure 4.4.

Stratégie de validation des entrées : contraignez, rejetez et assainissez la saisie

Figure 4.4
Stratégie de validation des entrées : contraignez, rejetez et assainissez la saisie

Pour créer une stratégie efficace de validation des entrées, n'oubliez pas les approches suivantes et les compromis qu'elles supposent :

  • Contraindre les entrées.

  • Valider le type, la longueur, le format et la plage de données.

  • Rejeter les données incorrectes connues.

  • Assainir la saisie.

Contraindre les entrées

La contrainte des entrées consiste à n'autoriser que la saisie de données correctes. C'est l'approche de prédilection. L'idée est de définir un filtre d'entrées acceptables en fixant le type, la longueur, le format et la plage de données. Définissez ce qu'est une saisie acceptable pour les champs de votre application et imposez cette définition. Rejetez tout le reste comme des données incorrectes.

La contrainte des entrées peut impliquer la définition de jeux de caractères sur le serveur afin de pouvoir établir la forme canonique de la saisie de façon localisée.

Valider le type, la longueur, le format et la plage de données

Exercez un contrôle strict des données en entrée chaque fois que c'est possible, par exemple, dans les classes utilisées pour manipuler et traiter les données en entrée et dans les routines d'accès aux données. Par exemple, utilisez des procédures stockées paramétrées pour l'accès aux données afin de bénéficier du contrôle strict des champs d'entrée.

La longueur des champs de chaînes peut également être vérifiée ainsi que le format, dans de nombreux cas. Par exemple, les codes ZIP, les numéros d'identification personnels, etc., ont des formats bien définis qui peuvent être validés en utilisant des expressions régulières. La vérification approfondie n'est pas seulement une bonne pratique de programmation ; elle rend plus difficile l'exploitation de votre code par un attaquant. Ce dernier peut échapper à votre vérification de type, mais la vérification de la longueur peut rendre plus difficile l'exécution de son attaque favorite.

Rejeter les données incorrectes connues

Refusez les données « incorrectes » ; toutefois, ne comptez pas uniquement sur cette approche. Elle est généralement moins efficace que l'utilisation de l'approche « autoriser » décrite précédemment et elle s'avère plus efficace en combinaison avec une autre. Refuser des données incorrectes suppose que votre application connaisse toutes les variations de la saisie malveillante. N'oubliez pas qu'il existe de nombreuses manières de représenter les caractères. C'est une autre raison pour laquelle l'approche « autoriser » est préférable.

Si elle est utile pour les applications déjà déployées et lorsque vous ne pouvez pas vous permettre de procéder à des modifications importantes, l'approche « refuser » n'est pas aussi robuste que l'approche « autoriser » car les données incorrectes, par exemple les modèles qui peuvent être utilisés pour identifier des attaques courantes, ne restent pas constantes. Les données correctes restent constantes tandis que la plage des données incorrectes peut évoluer dans le temps.

Assainir la saisie

L'assainissement consiste à rendre saines des données potentiellement malveillantes. Il peut être utile lorsque la plage de données autorisée en entrée ne peut garantir que la saisie est saine. L'assainissement inclut tout ce qui va de la suppression d'un caractère nul à la fin d'une chaîne fournie par l'utilisateur à l'échappement de valeurs afin qu'elles soient traitées comme des caractères littéraux.

Un autre exemple courant d'assainissement de la saisie dans les applications Web est l'utilisation de codage d'URL ou de codage HTML pour « emballer » les données et les traiter comme du texte littéral plutôt que comme un script exécutable. Les méthodes HtmlEncode échappent les caractères HTML, et les méthodes UrlEncode codent une URL afin qu'elles constituent une requête URI valide.

En pratique

Les exemples ci-dessous s'appliquent à des champs d'entrée courants, utilisant les approches précédentes :

  • Champ Nom. C'est un bon exemple dans lequel la contrainte de l'entrée est appropriée. Dans ce cas, vous pouvez autoriser les données de chaîne de la plage ASCII A–Z et a–z, ainsi que les traits d'union et les apostrophes courbes (ces dernières n'ont pas de signification pour SQL), de manière à pouvoir traiter des noms tels que O'Dell. Vous pouvez également limiter la longueur maximale de la chaîne attendue.

  • Champ Quantité. Voici un autre cas dans lequel la contrainte de la saisie fonctionne bien. Dans cet exemple, vous pouvez utiliser une restriction de type et de plage simple. Par exemple, il se peut que les données d'entrée doivent être un entier positif entre 0 et 1000.

  • Champ texte de forme libre. Il peut s'agir par exemple de champs de commentaire dans des forums de discussion. Dans ce cas, vous pouvez autoriser les lettres et les espaces, ainsi que les caractères courants tels que les apostrophes, les virgules et les traits d'union. Le jeu autorisé n'inclut pas les signes plus grand que et plus petit que, les parenthèses et les accolades.

    Certaines applications peuvent autoriser les utilisateurs à marquer leur texte en utilisant un jeu fini de caractères script, tels que gras « <b> », italique « <i> », ou même inclure un lien vers leur URL favorite. Dans le cas d'une URL, votre validation doit coder la valeur afin qu'elle soit traitée comme telle.

    Pour plus d'informations concernant la validation des champs de texte libre, consultez « Validation des entrées » dans le Module 10, « Création de pages et de contrôles ASP.NET sécurisés ».

  • Une application Web existante qui ne valide pas l'entrée de l'utilisateur. Dans un scénario idéal, l'application vérifie la validité de la saisie pour chaque champ ou point d'entrée. Toutefois, si l'une de vos applications Web existantes ne valide pas l'entrée de l'utilisateur, vous devez adopter une solution temporaire pour atténuer les risques, jusqu'à ce que vous puissiez améliorer la stratégie de validation de saisie de votre application. Si aucune des approches suivantes ne permet de traiter de la saisie de manière sécurisée, puisque tout dépend de l'origine des entrées et de leur utilisation dans votre application, elles servent aujourd'hui de correctifs rapides améliorer à court terme la sécurité :

    • Entrée d'utilisateur en codage HTML et codage URL lors de la réécriture vers le client. Dans ce cas, l'hypothèse est qu'aucune entrée n'est traitée comme du HTML et que toutes les sorties sont récrites dans une forme protégée. C'est l'assainissement en action.

    • Rejet des caractères script malveillants. C'est le cas du rejet des entrées connues comme étant incorrectes. Dans ce cas, un jeu configurable de caractères malveillants est utilisé pour rejeter la saisie. Comme indiqué précédemment, le problème de cette approche est que les données incorrectes dépendent du contexte.

Pour plus d'informations et pour des exemples concernant le codage, l'utilisation d'expressions régulières et les contrôles de validation ASP.NET, consultez « Validation des entrées » dans le Module 10, « Création de pages et de contrôles ASP.NET sécurisés ».

Authentification

L'authentification est le processus consistant à déterminer l'identité de l'appelant. Trois aspects doivent être pris en considération :

  • Identifier où l'authentification est nécessaire dans votre application. Elle est généralement requise chaque fois qu'une limite sécurisée est franchie. Les limites sécurisées incluent généralement les assemblys, les processus et les hôtes.

  • Validez qui est l'appelant. Les utilisateurs s'authentifient en général à l'aide de noms et de mots de passe.

  • Identifiez l'utilisateur sur des requêtes ultérieures. Ceci nécessite une forme ou une autre de jeton d'authentification.

De nombreuses applications Web utilisent un mécanisme de mot de passe pour authentifier les utilisateurs, dans lequel ils fournissent un nom d'utilisateur et un mot de passe sous forme HTML. Les problèmes et les questions à prendre ici en considération sont les suivants :

  • Les noms d'utilisateur et les mots de passe sont-ils envoyés en texte brut par des canaux non sécurisés ? Si c'est le cas, un attaquant peut effectuer des écoutes clandestines avec un logiciel de surveillance de réseau pour capturer les informations d'identification. La contre-mesure consiste ici à sécuriser le canal de communication en utilisant Secure Socket Layer (SSL).

  • Comment les informations d'identification sont-elles stockées ? Si vous stockez les noms d'utilisateur et les mots de passe en texte brut, que ce soit dans des fichiers ou dans une base de données, vous vous exposez à des ennuis. Que se passe-t-il si votre répertoire d'application est mal configuré et qu'un attaquant navigue jusqu'au fichier et en télécharge le contenu pour y ajouter un nouveau compte de connexion privilégié ? Que se passe-t-il si un administrateur mécontent dérobe votre base de données de noms d'utilisateur et de mots de passe ?

  • Comment les informations d'identification sont-elles vérifiées ? Il n'est pas nécessaire de stocker les mots de passe des utilisateurs si le seul but est de vérifier que l'utilisateur connaît la valeur du mot de passe. À la place, vous pouvez stocker un vérificateur sous la forme d'une valeur de hachage et recalculer le hachage en utilisant la valeur fournie par l'utilisateur au cours du processus de connexion. Pour atténuer la menace des attaques de dictionnaire contre le magasin des informations d'identification, utilisez des mots de passe fiables et combinez au hachage du mot de passe une valeur salt générée de façon aléatoire.

  • Comment l'utilisateur authentifié est-il identifié après la connexion initiale ? Une forme ou une autre de ticket d'authentification, par exemple un cookie d'authentification, est nécessaire. Comment le cookie est-il sécurisé ? S'il est envoyé sur un canal non sécurisé, un attaquant peut capturer le cookie et l'utiliser pour accéder à l'application. Le vol d'un cookie d'authentification permet de détourner une connexion.

Les pratiques suivantes visent à améliorer l'authentification de vos applications Web :

  • Séparer les zones publiques et restreintes.

  • Utiliser des stratégies de verrouillage pour les comptes des utilisateurs finaux.

  • Prendre en charge les périodes d'expiration des mots de passe.

  • Garder la possibilité de désactiver les comptes.

  • Ne pas stocker les mots de passe dans des magasins d'utilisateurs.

  • Exiger des mots de passe fiables.

  • Ne pas envoyer de mots de passe sur le réseau en texte brut.

  • Protéger les cookies d'authentification.

Séparer les zones publiques et restreintes

Une zone publique de votre site est accessible de façon anonyme par n'importe quel utilisateur. Les zones restreintes ne sont accessibles qu'à certaines personnes et les utilisateurs doivent s'authentifier auprès du site. Considérons un site Web classique de vente au détail. Vous pouvez parcourir le catalogue de produits de façon anonyme. Lorsque vous ajoutez des éléments à votre panier d'achat, l'application vous identifie à votre identificateur de session. Enfin, lorsque vous passez une commande, vous effectuez une transaction sécurisée. Pour cela, vous devez vous connecter pour authentifier votre transaction sur SSL.

En partitionnant votre site en zones d'accès publiques et restreintes, vous pouvez appliquer des règles distinctes d'authentification et d'autorisation sur le site et limiter l'utilisation de SSL. Pour éviter la réduction inutile des performances associée à SSL, concevez votre site pour limiter l'utilisation de SSL aux zones qui nécessitent un accès authentifié.

Utiliser des stratégies de verrouillage pour les comptes des utilisateurs finaux

Désactivez les comptes des utilisateurs finaux ou écrivez des événements dans un journal après un nombre défini d'échecs de tentatives de connexion. Si vous utilisez l'authentification Windows, par exemple NTLM ou le protocole Kerberos, ces stratégies peuvent être configurées et appliquées automatiquement par le système d'exploitation. Avec l'authentification par formulaire, ces stratégies sont de la responsabilité de l'application et doivent être intégrées à la conception de l'application.

Veillez au fait que les stratégies de verrouillage de comptes ne peuvent faire l'objet d'abus dans les attaques de refus de service. Par exemple, des comptes de service par défaut bien connus tels que IUSR_MACHINENAME doivent être remplacés par des noms de compte personnalisés pour éviter qu'un attaquant qui obtient le nom du serveur Web Internet Information Services (IIS) ne verrouille ce compte critique.

Prendre en charge les périodes d'expiration des mots de passe

Les mots de passe ne doivent pas être statiques et doivent être modifiés dans le cadre de la maintenance régulière des mots de passe par l'intermédiaire de périodes d'expiration des mots de passe. Envisagez de fournir ce type de fonctionnalité durant la phase de conception de l'application.

Garder la possibilité de désactiver les comptes

Si le système est compromis, avoir la possibilité d'invalider délibérément les informations d'identification ou de désactiver les comptes peut éviter des attaques supplémentaires.

Ne pas stocker les mots de passe dans des magasins d'utilisateurs

Si vous devez vérifier des mots de passe, il n'est pas nécessaire de les stocker en tant que tels. À la place, stockez une valeur de hachage unidirectionnelle et recalculez le hachage à l'aide des mots de passe fournis par l'utilisateur. Pour atténuer la menace des attaques de dictionnaire contre le magasin des utilisateurs, utilisez des mots de passe fiables et intégrez une valeur de salt générée de façon aléatoire au mot de passe.

Exiger des mots de passe fiables

Ne facilitez pas la tâche des attaquants qui cherchent à découvrir les mots de passe. Il existe de nombreux conseils, mais il est généralement recommandé d'exiger un minimum de huit caractères et un mélange de caractères majuscules et minuscules, de nombres et de caractères spéciaux. Que vous utilisiez la plate-forme pour imposer ces règles à votre place ou que vous développiez votre propre validation, cette étape est nécessaire pour contrer les attaques par force brute dans lesquelles un attaquant tente de découvrir un mot de passe par des séquences systématiques d'essais/erreurs. Utilisez des expressions régulières valider les mots de passe fiables.

Pour des exemples d'expressions régulières favorisant la validation des mots de passe, consultez « Validation des entrées » dans le Module 10, « Création de pages et de contrôles ASP.NET sécurisés ».

Ne pas envoyer de mots de passe sur le réseau en texte brut

Les mots de passe en texte brut envoyés sur un réseau sont vulnérables aux écoutes clandestines. Pour faire face à cette menace, sécurisez le canal de communication, par exemple en utilisant SSL pour crypter le trafic.

Protéger les cookies d'authentification

Le vol d'un cookie d'authentification permet de détourner une connexion. Protégez les tickets d'authentification à l'aide du cryptage et de canaux de communication sécurisés. Limitez également le délai pendant lequel un ticket d'authentification reste valide, pour contrer la menace d'usurpation pouvant résulter d'attaques par relecture, dans lesquelles un attaquant capture le cookie et l'utilise pour accéder à votre site de façon illicite. La réduction du temps d'expiration des cookies n'empêche pas les attaques par relecture mais limite le temps pendant lequel un attaquant peut accéder au site en utilisant le cookie volé.

Autorisation

L'autorisation détermine ce que l'identité authentifiée peut faire et les ressources accessibles. Une autorisation incorrecte ou faible se traduit par la divulgation d'informations et la falsification des données. La défense renforcée est le principe de sécurité clé à appliquer à la stratégie d'autorisation de votre application.

Les pratiques suivantes visent à améliorer l'autorisation de vos applications Web :

  • Utiliser plusieurs gardes-barrières.

  • Restreindre l'accès de l'utilisateur aux ressources de niveau système.

  • Déterminer le niveau de détail des autorisations.

Utiliser plusieurs gardes-barrières

Du côté serveur, vous pouvez utiliser des stratégies de protocole de sécurité IP (IPSec) pour offrir des restrictions visant à restreindre la communication de serveur à serveur. Par exemple, une stratégie IPSec doit empêcher tout hôte n'étant pas un serveur Web désigné de se connecter à un serveur de base de données. IIS permet les autorisations Web et les restrictions IP/DNS (Internet Protocol/ Domain Name System). Les autorisations Web IIS s'appliquent à toutes les ressources demandées sur HTTP quel que soit l'utilisateur. Elles n'offrent pas de protection si un attaquant parvient à se connecter au serveur. Pour cela, les autorisations NTFS vous permettent de spécifier des listes de contrôle d'accès par utilisateur. Enfin, ASP.NET fournit l'autorisation d'accès à l'URL et l'autorisation d'accès au fichier avec les demandes d'autorisation principales. En combinant ces gardes-barrières, vous pouvez développer une stratégie d'autorisation efficace.

Restreindre l'accès de l'utilisateur aux ressources de niveau système

Les ressources de niveau système incluent les fichiers, les dossiers, les clés de registre, les objets Active Directory, les objets des bases de données, les journaux d'événement, etc. Utilisez les ACL (Access Control Lists) de Windows pour limiter les utilisateurs pouvant accéder aux ressources et les types d'opérations qu'ils peuvent effectuer. Soyez particulièrement attentif aux comptes utilisateurs Internet anonymes ; verrouillez-les avec des ACL sur les ressources qui refusent explicitement l'accès aux utilisateurs anonymes.

Pour plus d'informations concernant le verrouillage des comptes utilisateurs Internet anonymes avec des ACL Windows, voir Module 16, « Sécurisation de votre serveur Web ».

Déterminer le niveau de détail des autorisations

Il existe trois modèles d'autorisation communs, chacun avec des degrés variés de granularité et d'évolutivité.

L'approche la plus fine repose sur l'emprunt d'identité. L'accès aux ressources se produit en utilisant le contexte de sécurité de l'appelant. Les ACL Windows sur les ressources sécurisées (généralement des fichiers ou des tables, ou les deux) déterminent si l'appelant est autorisé à accéder à la ressource. Si votre application fournit l'accès principalement à des ressources spécifiques de l'utilisateur, cette approche peut être valide. Elle présente l'avantage supplémentaire de permettre d'effectuer l'audit au niveau du système d'exploitation sur les couches de votre application, car le contexte de sécurité de l'appelant d'origine circule au niveau du système d'exploitation et est utilisé pour l'accès à la ressource. En revanche, cette approche se caractérise par une médiocre évolutivité d'application car le regroupement efficace de connexions pour l'accès à la base de données est impossible. Il en résulte que cette approche se rencontre plus fréquemment dans les applications intranet d'échelle limitée. Le modèle d'emprunt d'identité est illustré dans la figure 4.5.

Modèle d'emprunt d'identité offrant une granularité d'autorisation par utilisateur final

Figure 4.5
Modèle d'emprunt d'identité offrant une granularité d'autorisation par utilisateur final

L'approche la moins fine mais la plus évolutive utilise une identité qui détermine son mode d'accès aux ressources de l'application. Cette approche prend en charge le regroupement de connexions pour l'accès à la base de données mais elle signifie que les autorisations accordées à l'identité de l'application dans la base de données sont communes, quelle que soit l'identité de l'appelant d'origine. L'autorisation principale s'effectue au niveau logique intermédiaire de l'application en utilisant des rôles, qui regroupent les utilisateurs partageant les mêmes privilèges dans l'application. L'accès aux classes et aux méthodes est restreint en fonction de l'appartenance à un rôle de l'appelant. Pour prendre en charge la récupération de données par utilisateur, une approche courante consiste à inclure une colonne d'identité dans les tables de la base de données et à utiliser des paramètres de requête pour restreindre les données récupérées. Par exemple, vous pouvez transmettre l'identité de l'appelant d'origine à la base de données au niveau de l'application (et non du système d'exploitation) par l'intermédiaire des paramètres de procédures stockées, et écrire des requêtes semblables à ce qui suit :

SELECT field1, field2, field3 FROM Table1 WHERE {critères de recherche} AND 
UserName = @originalCallerUserName

Ce modèle est appelé sous-système approuvé ou parfois modèle de serveur approuvé. Il est illustré dans la figure 4.6.

Modèle de sous-système approuvé prenant en charge le regroupement de connexions pour l'accès à la base de données

Figure 4.6
Modèle de sous-système approuvé prenant en charge le regroupement de connexions pour l'accès à la base de données

La troisième option consiste à utiliser un ensemble limité d'identités pour l'accès à la ressource basé sur l'appartenance à un rôle de l'appelant. Il s'agit en réalité d'un hybride des deux modèles décrits précédemment. Les appelants sont mis en correspondance avec les rôles au niveau logique intermédiaire de l'application, et l'accès aux classes et aux méthodes est restreint en fonction de l'appartenance au rôle. L'accès à la ressource en aval s'effectue en utilisant un ensemble restreint d'identités déterminé par l'appartenance au rôle de l'appelant actuel. L'avantage de cette approche est que les autorisations peuvent être attribuées à des connexions distinctes dans la base de données, et le regroupement de connexions demeure efficace avec plusieurs groupes de connexions. Elle présente en revanche l'inconvénient suivant : la création de plusieurs jetons d'accès de thread pour établir différents contextes de sécurité afin d'accéder aux ressources en aval via l'authentification Windows est une opération privilégiée ; elle implique donc que l'on dispose de comptes de processus privilégiés. Ceci s'oppose au principe du moindre privilège. Le modèle hybride utilisant plusieurs identités de service sécurisées pour l'accès aux ressources en aval est illustré dans la figure 4.7.

Modèle hybride

Figure 4.7
Modèle hybride

Gestion de la configuration

Étudiez avec soin la fonctionnalité de gestion de configuration de votre application Web. La plupart des applications nécessitent des interfaces permettant aux développeurs de contenu, aux opérateurs et aux administrateurs de configurer l'application et de gérer des éléments tels que le contenu des pages Web, les comptes des utilisateurs, les informations de profil des utilisateurs et les chaînes de connexion à la base de données. Si l'administration distante est prise en charge, comment les interfaces d'administration sont-elles sécurisées ? Les conséquences d'une faille de sécurité dans une interface d'administration peuvent être graves, car l'attaquant finit souvent par utiliser les privilèges d'administrateur et dispose alors d'un accès direct au site entier.

Les pratiques suivantes visent à améliorer la sécurité de la gestion de la configuration de votre application Web :

  • Sécuriser vos interfaces d'administration.

  • Sécuriser vos magasins de configuration.

  • Gérer des privilèges d'administration séparés.

  • Utiliser les comptes de processus et de service les moins privilégiés.

Sécuriser vos interfaces d'administration

Il est important que la fonctionnalité de gestion de la configuration ne soit accessible qu'aux opérateurs et administrateurs autorisés. Un élément essentiel consiste à imposer une authentification sécurisée sur vos interfaces d'administration, par exemple en utilisant des certificats.

Si possible, limitez ou évitez d'utiliser l'administration à distance et exigez que les administrateurs se connectent localement. Si vous devez prendre en charge l'administration à distance, utilisez des canaux cryptés, par exemple, avec la technologie SSL ou VPN, du fait de la nature sensible des données transmises sur les interfaces d'administration. Envisagez également de limiter l'administration à distance à des ordinateurs du réseau interne en utilisant des stratégies IPSec, pour réduire encore le risque.

Sécuriser vos magasins de configuration

Les fichiers de configuration à base de texte, le registre et les bases de données sont des options courantes de stockage des données de configuration des applications. Si possible, évitez d'utiliser des fichiers de configuration dans l'espace Web de l'application pour éviter d'éventuelles vulnérabilités de configuration du serveur pouvant se traduire par le téléchargement des fichiers de configuration. Quelle que soit l'approche utilisée, sécurisez l'accès au magasin de configuration, par exemple en utilisant des ACL Windows ou des autorisations de la base de données. Évitez également de stocker des secrets en texte brut tels que des chaînes de connexion à la base de données ou des informations d'identification de compte. Sécurisez ces éléments en utilisant le cryptage et restreignez l'accès à la clé de registre, au fichier ou à la table contenant les données cryptées.

Gérer des privilèges d'administration séparés

Si la fonctionnalité prise en charge par les fonctions de gestion de configuration de votre application varie selon le rôle de l'administrateur, envisagez d'autoriser chaque rôle séparément en utilisant l'autorisation basée sur les rôles. Par exemple, la personne responsable de la mise à jour du contenu statique d'un site ne doit pas nécessairement être autorisée à modifier la limite de crédit d'un client.

Utiliser les comptes de processus et de service les moins privilégiés

Un aspect important de la configuration de votre application concerne les comptes de processus utilisés pour exécuter les comptes de processus et de service du serveur Web permettant l'accès aux ressources et systèmes se trouvant en aval. Vérifiez que ces comptes sont configurés avec le moins de privilèges possible. Si un attaquant réussit à prendre le contrôle d'un processus, l'identité de ce dernier doit avoir un accès extrêmement limité au système de fichiers et autres ressources système afin de limiter les dommages potentiels.

Données sensibles

Les applications qui traitent des informations privées des utilisateurs telles que les numéros de cartes de crédit, les adresses, les dossiers médicaux, etc., doivent veiller particulièrement à conserver la confidentialité et l'intégrité des données. En outre, les secrets utilisés par la mise en œuvre de l'application, tels que les mots de passe et les chaînes de connexion à la base de données, doivent être sécurisés. La sécurité des données sensibles est un problème lorsque les données sont stockées dans un stockage persistant et lorsqu'elles sont transmises sur le réseau.

Secrets

Les secrets incluent les mots de passe les chaînes de connexion à la base de données et les numéros de cartes de crédit. Les pratiques suivantes visent à améliorer la sécurité de la gestion des secrets de votre application Web :

  • Ne pas stocker les secrets si vous pouvez l'éviter.

  • Ne pas stocker les secrets dans le code.

  • Ne pas stocker les chaînes de connexion à la base de données, les mots de passe ou les clés en texte brut.

  • Éviter de stocker des secrets dans l'autorité de sécurité locale (LSA).

  • Utiliser une API de protection des données (DPAPI) pour le cryptage des secrets.

Ne pas stocker les secrets si vous pouvez l'éviter

Le stockage de secrets sous forme logicielle de façon entièrement sécurisée n'est pas possible. Un administrateur ayant un accès physique au serveur peut accéder aux données. Par exemple, il n'est pas nécessaire de stocker un secret lorsque vous devez uniquement vérifier si un utilisateur le connaît. Dans ce cas, vous pouvez stocker une valeur de hachage qui représente le secret et calculer le hachage en utilisant la valeur fournie par l'utilisateur pour vérifier s'il connaît l'information requise.

Ne pas stocker les secrets dans le code

Ne codez pas de secrets dans le code. Même si le code source n'est pas exposé sur le serveur Web, il est possible d'extraire des constantes de chaîne des fichiers exécutables compilés. Une vulnérabilité de la configuration peut permettre à un attaquant de récupérer l'exécutable.

Ne pas stocker les chaînes de connexion à la base de données, les mots de passe ou les clés en texte brut

Évitez de stocker des secrets tels que des chaînes de connexion à la base de données, des mots de passe ou des clés en texte brut. Utilisez le cryptage et stockez des chaînes cryptées.

Éviter de stocker des secrets dans l'autorité de sécurité locale (LSA)

Évitez le LSA car votre application nécessite des privilèges d'administration pour y accéder. Ceci s'oppose au principe de sécurité essentiel du moindre privilège. De plus, le LSA ne peut stocker des secrets que dans un nombre restreint d'emplacements. Une meilleure approche consiste à utiliser DPAPI, disponible avec les systèmes d'exploitation Microsoft Windows® 2000 et ultérieurs.

Utiliser DPAPI pour le cryptage des secrets

Pour stocker des secrets tels que des chaînes de connexion à la base de données ou des informations d'identification de compte de service, utilisez DPAPI. Le principal avantage de l'utilisation de DPAPI est que le système de la plate-forme gère la clé de cryptage/décryptage et ceci n'entrave pas le fonctionnement de l'application. La clé est associée au compte utilisateur Windows ou à un ordinateur particulier, selon les indicateurs transmis aux fonctions DPAPI.

DPAPI est mieux adapté au cryptage des informations pouvant être recréées manuellement lorsque les clés principales ont été perdues, du fait, par exemple, qu'un serveur endommagé nécessite la réinstallation du système d'exploitation. Les données ne pouvant pas être récupérées du fait que vous ne connaissez pas leur valeur en texte brut, par exemple les numéros de la carte de crédit d'un client, nécessitent une autre approche qui utilise la cryptographie classique symétrique à base de clé, par exemple le processus triple–DES.

Pour plus d'informations concernant l'utilisation de DPAPI à partir des applications Web, consultez le Module 10, « Création de pages et de contrôles ASP.NET sécurisés ».

Données sensibles par utilisateur

Les données sensibles telles que les informations d'authentification d'ouverture de session et les données au niveau de l'application telles que les numéros de cartes de crédit, les numéros de comptes bancaires, etc., doivent être protégées. La confidentialité par le cryptage et l'intégrité par les codes d'authentification des messages (MAC) sont les principaux éléments.

Les pratiques suivantes visent à améliorer la sécurité des données sensibles par utilisateur de votre application Web :

  • Récupérer les données sensibles à la demande.

  • Crypter les données ou sécuriser le canal de communication.

  • Ne pas stocker de données sensibles dans des cookies persistants.

  • Ne pas transmettre de données sensibles avec le protocole HTTP-GET.

Récupérer les données sensibles à la demande

L'approche de prédilection consiste à récupérer les données sensibles à la demande lorsqu'elles sont nécessaires, plutôt que de les conserver à l'état persistant ou les mettre en cache en mémoire. Par exemple, récupérez le secret crypté si nécessaire, décryptez-le, utilisez-le, puis effacez la mémoire (variable) utilisée pour stocker le secret en texte brut. Si les performances en pâtissent, vous disposez des options suivantes :

  • Mettre en cache le secret crypté.

  • Mettre en cache le secret en texte brut.

Mettre en cache le secret crypté

Récupérez le secret lors du chargement de l'application et mettez ensuite le secret en cache en mémoire sous forme cryptée, pour le décrypter lorsque l'application l'utilise. Supprimez la copie en texte brut lorsqu'elle n'est plus nécessaire. Cette approche évite d'accéder au magasin de données à chaque demande.

Mettre en cache le secret en texte brut

Évitez la surcharge liée au décryptage du secret à plusieurs reprises et stockez une copie en texte brut du secret dans la mémoire. Ceci constitue l'approche la moins sécurisée, mais offre les performances optimales. Testez les performances des autres approches avant de conclure que les gains supplémentaires de performances compensent les risques supplémentaires en matière de sécurité.

Crypter les données ou sécuriser le canal de communication

Si vous envoyez des données sensibles sur le réseau à un client, cryptez les données ou sécurisez le canal de communication. Une pratique courante consiste à utiliser SSL entre le client et le serveur Web. Entre les serveurs, une approche de plus en plus courante consiste à utiliser IPSec. Pour sécuriser les données sensibles qui circulent par plusieurs intermédiaires, par exemple les messages Simple Object Access Protocol (SOAP) de service Web, utilisez le cryptage au niveau du message.

Ne pas stocker de données sensibles dans des cookies persistants

Évitez de stocker des données sensibles dans des cookies persistants. Si vous stockez des données en texte brut, l'utilisateur final est en mesure de les voir et de les modifier. Si vous cryptez les données, la gestion de la clé peut être un problème. Par exemple, si la clé utilisée pour crypter les données dans le cookie a expiré et a été recyclée, la nouvelle clé ne peut décrypter le cookie persistant transmis par le navigateur à partir du client.

Ne pas transmettre de données sensibles avec le protocole HTTP-GET

Évitez de stocker des données sensibles en utilisant le protocole HTTP-GET qui utilise des chaînes de requête pour transmettre les données. Les données sensibles ne peuvent être sécurisées en utilisant des chaînes de requête et ces dernières sont souvent enregistrées par le serveur.

Gestion des sessions

Les applications Web sont construites sur le protocole HTTP sans état, c'est pourquoi la responsabilité de la gestion des sessions repose sur le niveau de l'application. La sécurité d'une session est essentielle pour la sécurité globale d'une application.

Les pratiques suivantes visent à améliorer la sécurité de la gestion des sessions de votre application Web :

  • Utiliser SSL pour protéger les cookies d'authentification de la session.

  • Crypter le contenu des cookies d'authentification.

  • Limiter la durée de vie d'une session.

  • Protéger l'état d'une session des accès non autorisés.

Utiliser SSL pour protéger les cookies d'authentification de la session

Ne transmettez pas de cookies d'authentification sur des connexions HTTP. Configurez la propriété de cookie sécurisé au sein des cookies d'authentification, qui indique aux navigateurs de ne renvoyer les cookies au serveur que sur des connexions HTTPS. Pour plus d'informations, consultez le Module 10, « Création de pages et de contrôles ASP.NET sécurisés ».

Crypter le contenu des cookies d'authentification

Cryptez le contenu des cookies même si vous utilisez SSL. Ceci empêche un attaquant de voir ou de modifier le cookie s'il parvient à le dérober dans le cadre d'une attaque XSS. Dans ce cas, l'attaquant peut continuer d'utiliser le cookie pour accéder à votre application, mais tant que ce dernier reste valide.

Limiter la durée de vie d'une session

Limitez la durée de vie des sessions pour atténuer le risque d'attaque de piratage de session et par relecture. Plus la session est courte, moins l'attaquant a de temps pour capturer un cookie de session et l'utiliser pour accéder à votre application.

Protéger l'état d'une session des accès non autorisés

Étudiez de quelle manière l'état de la session doit être stocké. Pour des performances optimales, vous pouvez stocker l'état de la session dans l'espace d'adressage du processus de l'application Web. Toutefois, cette approche présente une évolutivité limitée et a des implications dans les scénarios de batteries de serveurs Web, dans lesquels on ne peut garantir que les requêtes d'un même utilisateur seront gérées par le même serveur. Dans un tel scénario, un magasin d'état hors processus sur un serveur d'état dédié ou un magasin d'état persistant dans une base de données partagée sont nécessaires. ASP.NET prend en charge les trois options.

Vous devez sécuriser la liaison de l'application Web vers le magasin d'état en utilisant IPSec ou SSL pour atténuer le risque d'écoute clandestine. Étudiez également de quelle manière l'application Web doit être authentifiée par le magasin d'état. Utilisez l'authentification Windows chaque fois que c'est possible pour éviter de transmettre des informations d'authentification en texte brut sur le réseau et pour bénéficier des stratégies de comptes sécurisés de Windows.

Cryptographie

Dans sa forme fondamentale, la cryptographie apporte :

  • La confidentialité. Ce service préserve la confidentialité d'un secret.

  • La non-répudiation (authenticité). Ce service vérifie qu'un utilisateur ne peut refuser d'envoyer un message particulier.

  • L'inviolabilité (intégrité). Ce service empêche la modification des données.

  • L'authentification. Ce service vérifie l'identité de l'expéditeur d'un message.

Les applications Web utilisent fréquemment la cryptographie pour sécuriser les données dans des magasins persistants ou lorsqu'elles sont transmises sur des réseaux. Les pratiques suivantes visent à améliorer la sécurité de votre application Web lorsque vous utilisez la cryptographie :

  • Ne pas développer votre propre cryptographie.

  • Conserver les données non cryptées à proximité de l'algorithme.

  • Utiliser l'algorithme et la taille de clé corrects.

  • Sécuriser vos clés de cryptage.

Ne pas développer votre propre cryptographie

Les algorithmes et routines cryptographiques sont notoirement difficiles à développer si l'on cherche à obtenir de bons résultats. Il en résulte qu'il est préférable d'utiliser les services cryptographiques testés et éprouvés fournis par la plate-forme. Ceci inclut le .NET Framework et le système d'exploitation sous-jacent. Ne développez pas d'implémentations personnalisées qui se traduisent fréquemment par une protection médiocre.

Conserver les données non cryptées à proximité de l'algorithme

Lorsque vous transmettez du texte brut à un algorithme, ne récupérez pas les données avant d'être prêt à les traiter et stockez-les dans le moins de variables possible.

Utiliser l'algorithme et la taille de clé corrects

Il est important de vérifier que vous choisissez l'algorithme adapté à la tâche et que vous utilisez une taille de clé offrant un degré de sécurité suffisant. Les tailles de clé plus élevées augmentent généralement la sécurité. La liste suivante résume les principaux algorithmes avec les tailles de clés de chacun d'entre eux :

  • Data Encryption Standard (DES) clé 64 bits (8 octets)

  • TripleDES clé 128 bits ou clé 192 bits (16 ou 24 octets)

  • Rijndael clés 128 – 256 bits (16 – 32 octets)

  • RSA clés 384 – 16384 bits (48 – 2048 octets)

Pour le cryptage de données volumineuses, utilisez l'algorithme de cryptage symétrique TripleDES. Pour le cryptage plus lent et plus robuste des données volumineuses, utilisez Rijndael. Pour crypter les données devant être stockées sur de courtes périodes, vous pouvez envisager d'utiliser un algorithme plus rapide mais moins fiable tel que DES. Pour les signatures numériques, utilisez Rivest, Shamir et Adleman (RSA) ou Digital Signature Algorithm (DSA). Pour le hachage, utilisez Secure Hash Algorithm (SHA)1.0. Pour les hachages avec clé, utilisez Hash-based Message Authentication Code (HMAC) SHA1.0.

Sécuriser vos clés de cryptage

Une clé de cryptage est un numéro secret utilisé comme entrée dans les processus de cryptage et de décryptage. Pour que les données cryptées restent sécurisées, la clé doit être protégée. Si un attaquant compromet la clé de décryptage, vos données cryptées ne sont plus sécurisées.

Les pratiques suivantes aident à sécuriser vos clés de cryptage :

  • Utiliser DPAPI pour éviter de gérer la clé.

  • Recycler périodiquement vos clés.

Utiliser DPAPI pour éviter de gérer la clé

Comme indiqué précédemment, l'un des principaux avantages de l'utilisation de DPAPI tient à ce que la gestion de la clé est assurée par le système d'exploitation. La clé utilisée par DPAPI provient du mot de passe associé au compte de processus qui appelle les fonctions DPAPI. DPAPI vous permet de confier la gestion de la clé au système d'exploitation.

Recycler périodiquement vos clés

Généralement, un secret statique a plus de chances d'être découvert avec le temps. Les questions à ne pas oublier sont les suivantes : L'avez-vous écrit quelque part ? Est-ce que Bernard, l'administrateur des secrets, va changer de poste au sein de l'entreprise ou la quitter ? N'utilisez pas exagérément les clés.

Manipulation des paramètres

Dans les attaques de manipulation des paramètres, l'attaquant modifie les données envoyées entre le client et l'application Web. Il peut s'agir de données envoyées en utilisant des chaînes de requête, des champs de formulaires, des cookies, ou dans des en-têtes HTTP. Les pratiques suivantes aident à sécuriser la manipulation des paramètres de vos applications Web :

  • Crypter l'état des cookies sensibles.

  • Vérifier que les utilisateurs ne contournent pas vos vérifications.

  • Valider toutes les valeurs envoyées par le client.

  • Ne pas vous fier aux informations d'en-têtes HTTP.

Crypter l'état des cookies sensibles

Les cookies peuvent contenir des données sensibles telles que les identificateurs de session ou les données utilisées dans le cadre du processus d'autorisation côté serveur. Pour protéger ce type de données des manipulations non autorisées, utilisez la cryptographie pour crypter le contenu du cookie.

Vérifier que les utilisateurs ne contournent pas vos vérifications

Vérifiez que les utilisateurs ne contournent pas vos vérifications en manipulant des paramètres. Les paramètres d'URL peuvent être manipulés par les utilisateurs finaux dans la zone d'adresse du navigateur. Par exemple, l'URL http://www.<VotreSite>/<VotreApp>/sessionId=10 a une valeur de 10 qui peut être remplacée par un nombre aléatoire afin de recevoir des résultats différents. Veillez à vérifier cela dans le code côté serveur, et non dans le JavaScript côté client, qui peut être désactivé dans le navigateur.

Valider toutes les valeurs envoyées par le client

Restreignez les champs auxquels peut accéder l'utilisateur pour les modifier et validez toutes les valeurs en provenance du client. Si vos champs de formulaire contiennent des valeurs prédéfinies, les utilisateurs peuvent les modifier et les renvoyer pour recevoir des résultats différents. N'autorisez que les valeurs dont vous savez qu'elles sont correctes, chaque fois que c'est possible. Par exemple, si le champ d'entrée concerne un code postal, seuls les entrées correspondant à un code postal doivent être autorisées.

Ne pas vous fier aux informations d'en-têtes HTTP

Les en-têtes HTTP sont envoyés au début des requêtes HTTP et des réponses HTTP. Votre application Web doit vérifier qu'elle ne base aucune décision de sécurité sur des informations des en-têtes HTTP car il est facile pour un attaquant de manipuler l'en-tête. Par exemple, le champ referer de l'en-tête contient l'URL de la page Web d'où émane la requête. Ne prenez aucune décision de sécurité basée sur la valeur du champ « referer », par exemple pour vérifier si la requête émane d'une page générée par l'application Web, car ce champ est aisément falsifiable.

Gestion des exceptions

La gestion sécurisée des exceptions peut aider à prévenir certaines attaques de refus de service au niveau de l'application et peut également servir à empêcher le renvoi au client d'informations système utiles aux attaquants. Par exemple, sans une gestion appropriée des exceptions, les informations telles que le schéma détaillé d'une base de données, les versions de système d'exploitation, la trace de la pile, les noms de fichiers et les informations de chemin d'accès, les chaînes de requête SQL et autres informations précieuses pour un attaquant peuvent être renvoyées au client.

Une bonne approche consiste à concevoir une solution de gestion centralisée des exceptions et de consignation et à étudier la possibilité de fournir des points de raccordement dans votre système de gestion des exceptions pour prendre en charge l'instrumentation et la surveillance centralisée afin d'aider les administrateurs système.

Les pratiques suivantes aident à sécuriser la gestion des exceptions de vos applications Web :

  • Ne pas renvoyer les informations au client.

  • Consigner les messages d'erreur détaillés.

  • Bloquer les exceptions.

Ne pas renvoyer les informations au client

En cas d'échec, n'exposez pas les informations pouvant se traduire par une divulgation d'informations. Par exemple, n'exposez pas les détails d'une trace de pile qui inclut des noms de fonction et des numéros de ligne dans le cas des versions de débogage (qui ne doivent pas être utilisées dans des serveurs de production). Renvoyez plutôt des messages d'erreur génériques au client.

Consigner les messages d'erreur détaillés

Envoyez des messages d'erreur détaillés au journal des erreurs. Envoyez le minimum d'informations au consommateur de votre service ou de votre application, comme un message d'erreur générique et un ID de journal d'erreur personnalisé pouvant être ensuite mappé vers le message détaillé des journaux d'événements. Veillez à ne pas enregistrer de mots de passe ou autres données sensibles.

Bloquer les exceptions

Utilisez la gestion structurée des exceptions et bloquez les conditions d'exception. Ceci évite de laisser votre application dans un état instable pouvant se traduire par la divulgation d'informations. Ceci protège en outre votre application des attaques de refus de service. Vous devez décider de quelle manière propager les exceptions de façon interne dans votre application et accorder une attention particulière à ce qui se passe à la frontière de l'application.

Pour plus d'informations sur la conception et l'implémentation d'une infrastructure de gestion des exceptions pour les applications .NET, reportez-vous à l'article MSDN « Exception Management Architecture Guide » à l'adresse http://msdn.microsoft.com/library/en-us/dnbda/html/exceptdotnet.asp.

Audit et journalisation

Vous devez analyser et consigner l'activité à travers les couches de votre application. Les journaux vous permettent de détecter les activités paraissant suspectes. Ils offrent souvent des indications précoces d'une offensive globale et aident à traiter les attaques de répudiation, dans lesquelles les utilisateurs refusent d'effectuer des actions. Les fichiers journaux peuvent être requis dans des procédures judiciaires pour prouver les malversations d'individus. En général, les audits qui font le plus autorité sont ceux générés au moment exact de l'accès à la ressource, par les routines chargées de cet accès.

Les pratiques suivantes visent à améliorer la sécurité de vos applications Web :

  • Analyser et consigner l'accès à travers les niveaux de l'application.

  • Étudier le flux des identités.

  • Consigner les événements majeurs.

  • Sécuriser les fichiers journaux.

  • Sauvegarder et analyser régulièrement les fichiers journaux.

Analyser et consigner l'accès à travers les niveaux de l'application

Analysez et consignez l'accès à travers les niveaux de l'application en termes de non-répudiation. Utilisez une combinaison de fonctions de consignation au niveau de l'application et d'analyse de plate-forme, telles que l'analyse Windows, IIS et SQL Server.

Étudier le flux des identités

Étudiez de quelle manière votre application va faire circuler l'identité de l'appelant à travers plusieurs couches de l'application. Vous avez deux possibilités principales. Vous pouvez faire circuler l'identité de l'appelant au niveau du système d'exploitation en utilisant la délégation de protocole Kerberos. Ceci vous permet d'utiliser l'analyse au niveau du système d'exploitation. L'inconvénient de cette approche est qu'elle nuit à l'évolutivité car elle signifie qu'il ne peut exister aucun regroupement de connexions efficace à la base de données sur la couche intermédiaire. Vous pouvez également faire circuler l'identité de l'appelant au niveau de l'application et utiliser des identités sécurisées pour accéder aux ressources principales. Avec cette approche, vous devez vous fier à la couche intermédiaire et ceci implique un risque potentiel de répudiation. Vous devez générer des journaux d'audit dans la couche intermédiaire, pouvant être corrélés avec les journaux d'audit principaux. Pour cela, vous devez vous assurer que les horloges des serveurs sont synchronisées, bien que Microsoft Windows 2000 et Active Directory le fassent automatiquement.

Consigner les événements majeurs

Les types d'événements devant être consignés incluent les tentatives de connexion réussies et ayant échoué, la modification des données, la récupération des données, les communications réseau et les fonctions d'administration telles que l'activation ou la désactivation de la consignation. Les journaux doivent inclure l'heure de l'événement, l'emplacement de l'événement avec le nom de la machine, l'identité de l'utilisateur actuel, l'identité du processus à l'origine de l'événement et une description détaillée de l'événement.

Sécuriser les fichiers journaux

Sécurisez les fichiers journaux en utilisant les ACL Windows et restreignez l'accès aux fichiers journaux. Ceci rend plus difficile leur falsification par les attaquants qui souhaitent effacer les traces de leur passage. Limitez le nombre d'individus qui peuvent manipuler les fichiers journaux. Ne les rendez accessibles qu'aux comptes hautement sécurisés tels que ceux des administrateurs.

Sauvegarder et analyser régulièrement les fichiers journaux

La consignation des activités ne présente aucun intérêt si les fichiers journaux ne sont jamais analysés. Les fichiers journaux doivent être supprimés régulièrement des serveurs de production. La fréquence de suppression dépend du niveau d'activité de votre application. Lors de la conception, vous devez prendre en compte la manière dont les fichiers journaux seront récupérés et déplacés vers des serveurs hors ligne à des fins d'analyse. Les protocoles et les ports supplémentaires ouverts sur le serveur Web à cette fin doivent être verrouillés de façon sécurisée.

Résumé des conseils de conception

Le tableau 4.1 résume les instructions de conception de ce module et les organise par catégorie de vulnérabilité de l'application.

Tableau 4.1 : Instructions de conception pour votre application

Catégorie

Instructions

Validation des entrées

Ne vous fiez pas à la saisie ; envisagez la validation centralisée des entrées.
Ne vous fiez pas à la validation côté client. Soyez prudent vis-à-vis des problèmes de canonisation. Contraignez, rejetez et assainissez la saisie. Validez le type, la longueur, le format et la plage des données.

Authentification

Partitionnez le site en zones anonyme, identifiée et authentifiée. Utilisez des mots de passe sûrs. Prenez en charge les périodes d'expiration des mots de passe et la désactivation des comptes. Ne stockez pas d'informations d'identification (utilisez des hachages unidirectionnels avec salt). Cryptez les canaux de communication pour protéger les jetons d'authentification. Ne transmettez les cookies d'authentification que sur des connexions HTTPS.

Autorisation

Utilisez les comptes les moins privilégiés. Envisagez la granularité de l'autorisation. Imposez la séparation des privilèges. Restreignez l'accès de l'utilisateur aux ressources de niveau système.

Gestion de la configuration

Utilisez des comptes de processus et de service les moins privilégiés. Ne stockez pas d'informations d'identification en texte brut. Utilisez l'authentification et l'autorisation renforcées sur les interfaces d'administration. N'utilisez pas le LSA. Sécurisez le canal de communication pour l'administration à distance. Évitez de stocker des données sensibles dans l'espace Web.

Données sensibles

Évitez de stocker des secrets. Cryptez les données sensibles sur le réseau. Sécurisez le canal de communication. Fournissez des contrôles d'accès renforcés sur les magasins de données sensibles. Ne stockez pas de données sensibles dans des cookies persistants. Ne transmettez pas de données sensibles avec le protocole HTTP-GET.

Gestion des sessions

Limitez la durée de vie d'une session. Sécurisez le canal. Cryptez le contenu des cookies d'authentification. Protégez l'état d'une session des accès non autorisés.

Cryptographie

Ne développez pas votre propre cryptographie. Utilisez les fonctions testées et éprouvées de la plate-forme. Conservez les données non cryptées à proximité de l'algorithme. Utilisez l'algorithme et la taille de clé corrects. Évitez la gestion des clés (utilisez DPAPI). Recyclez périodiquement vos clés. Stockez les clés dans un emplacement à accès restreint.

Manipulation des paramètres

Cryptez l'état des cookies sensibles. Ne vous fiez pas aux champs que le client peut manipuler (chaînes de requête, champs de formulaires, cookies, ou en-têtes HTTP). Validez toutes les valeurs envoyées par le client.

Gestion des exceptions

Utilisez une gestion structurée des exceptions. Ne révélez pas les informations sensibles d'implémentation de l'application. N'enregistrez pas les données privées telles que les mots de passe. Envisagez une infrastructure de gestion centralisée des exceptions.

Audit et journalisation

Identifiez les comportements malveillants. Sachez à quoi ressemble un trafic sain. Analysez et consignez l'activité à travers toutes les couches de votre application. Sécurisez l'accès aux fichiers journaux. Sauvegardez et analysez régulièrement les fichiers journaux.

Résumé

La sécurité doit imprégner chaque étape du cycle de développement du produit et doit constituer un point central de la conception de l'application. Soyez particulièrement attentif à la conception d'une stratégie robuste d'authentification et d'autorisation. Rappelez-vous également que la majorité des attaques au niveau de l'application reposent sur des données d'entrée malveillantes et une validation médiocre des entrées de l'application. Les conseils présentés dans ce module doivent vous aider à régler ces aspects ainsi que d'autres aspects délicats de la conception et de la construction d'applications sécurisées.

Informations complémentaires

Pour plus d'informations, reportez-vous aux ressources suivantes :

Afficher:
© 2014 Microsoft