Comprendre la falsification de demandes intersites dans .NET

Vous ne pouvez créer des applications Web sécurisées qu'en tenant compte de la sécurité, dès le départ. Cela nécessite de penser aux moyens potentiels par lesquels une personne pourrait attaquer votre site lorsque vous créez chaque page, formulaire et action. Il faut également comprendre les types de problèmes de sécurité les plus courants et savoir comment les résoudre..

Le type de faille de sécurité le plus courant dans une page Web permet à un attaquant d'exécuter des commandes pour le compte d'un utilisateur, mais à l'insu de l'utilisateur. L'attaque de falsification de requête intersite exploite la confiance qu'un site Web a déjà établie avec le navigateur Web d'un utilisateur..

Dans ce didacticiel, nous verrons en quoi consiste une attaque par falsification de requêtes intersites et comment elle est exécutée. Ensuite, nous allons créer une application ASP.NET MVC simple vulnérable à cette attaque et la réparer pour l'empêcher de se reproduire..


Qu'est-ce qu'une falsification de requête intersite??

L'attaque de falsification de requête inter-site suppose tout d'abord que la victime s'est déjà authentifiée sur un site Web cible, tel qu'un site bancaire, Paypal ou un autre site à attaquer. Cette authentification doit être stockée de manière à ce que si l'utilisateur quitte le site et y retourne, il est toujours considéré comme connecté par le site Web cible. L’attaquant doit ensuite obliger la victime à accéder à une page ou à un lien permettant d’exécuter une demande ou de publier sur le site Web cible. Si l'attaque fonctionne, le site Web cible verra une demande émaner de la victime et l'exécutera en tant qu'utilisateur. Cela permet en fait à l'attaquant d'exécuter toute action souhaitée sur le site Web ciblé en tant que victime. Le résultat potentiel pourrait transférer de l'argent, réinitialiser un mot de passe ou modifier une adresse e-mail sur le site Web ciblé..

Comment fonctionne l'attaque

Le fait d’amener la victime à utiliser un lien ne nécessite pas qu’elle clique sur un lien. Un simple lien image pourrait suffire:

Inclure un lien comme celui-ci sur un post de forum, un commentaire de blog ou un site de réseau social apparemment inoffensif pourrait attirer l'attention de l'utilisateur. Des exemples plus complexes utilisent JavaScript pour créer une demande de publication HTTP complète et l'envoyer au site Web cible..


Construction d'une application Web vulnérable dans ASP.NET MVC

Créons une simple application ASP.NET MVC et restons vulnérable à cette attaque. J'utiliserai Visual Studio 2012 pour ces exemples, mais cela fonctionnera également dans Visual Studio 2010 ou Visual Web Developer 2010 fonctionnera si vous avez installé le support pour MVC 4, qui peut être téléchargé et installé à partir de Microsoft..


Commencez par créer un nouveau projet et choisissez d’utiliser le Projet Internet modèle. Soit View Engine fonctionnera, mais ici je vais utiliser le moteur de visualisation ASPX.

Nous allons ajouter un champ à la table UserProfile pour stocker une adresse électronique. Sous Explorateur de serveur développer Connexions de données. Vous devriez voir le Connexion par défaut créé avec les informations pour les connexions et les adhésions. Clic droit sur le Profil de l'utilisateur table et cliquez Définition de table ouverte. Sur la ligne vide sous Nom d'utilisateur table, nous allons ajouter une nouvelle colonne pour l'email. Nommez la colonne adresse électronique, donne le type nvarchar (MAX), et vérifier le Autoriser les null option. Maintenant, cliquez Mettre à jour enregistrer la nouvelle version de la table.

Cela nous donne un modèle de base d’une application Web, avec prise en charge de la connexion, très similaire à ce que beaucoup d’écrivains commençaient par essayer de créer une application. Si vous exécutez l'application maintenant, vous verrez qu'elle s'affiche et est fonctionnelle. presse F5 Ou utiliser DEBUG -> Démarrer le débogage du menu pour faire apparaître le site.


Créons un compte test que nous pouvons utiliser pour cet exemple. Clique sur le registre créer un compte avec n'importe quel nom d'utilisateur et mot de passe que vous souhaitez. Ici, je vais utiliser un compte appelé testuser. Après la création, vous verrez que je suis maintenant connecté en tant que testuser. Une fois que vous avez terminé, quittez et ajoutons une page à cette application pour permettre à l'utilisateur de modifier son courrier électronique..


Avant de créer cette page pour modifier l'adresse e-mail, nous devons d'abord apporter une modification à l'application afin que le code connaisse la nouvelle colonne que nous venons d'ajouter. Ouvrez le AccountModels.cs déposer sous le Des modèles dossier et mettre à jour le Profil de l'utilisateur classe pour correspondre à ce qui suit. Cela indique à la classe notre nouvelle colonne où nous allons stocker l'adresse électronique du compte..

[Table ("UserProfile")] Classe publique UserProfile [Key] [DatabaseGeneratedAttribute (DatabaseGeneratedOption.Identity)] public int UserId get; ensemble;  chaîne publique UserName get; ensemble;  chaîne publique EmailAddress get; ensemble; 

Ouvrez le AccountController.cs fichier. Après le Supprimer les logiques externes function ajoute le code suivant pour créer une nouvelle action. Ceci récupérera l'email actuel de l'utilisateur connecté et le transmettra à la vue pour l'action..

public ActionResult ChangeEmail () // Récupère la chaîne de l'utilisateur connecté nom_utilisateur = WebSecurity.CurrentUserName; chaîne currentEmail; using (UsersContext db = new UsersContext ()) UserProfile user = db.UserProfiles.FirstOrDefault (u => u.NomUtilisateur.ToLower () == nomutilisateur); currentEmail = user.EmailAddress;  return View (currentEmail); 

Nous devons également ajouter la vue correspondante pour cette action. Cela devrait être un fichier nommé ChangeEmail.aspx sous le Vues \ Compte dossier:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage"%>  Changer l'adresse email   

Changer l'adresse email

Adresse e-mail actuelle: <%= Model ?? "Pas d'email actuel"%>

<% using(Html.BeginForm()) %> <% %>

Cela nous donne une nouvelle page que nous pouvons utiliser pour changer l’adresse email de l’utilisateur actuellement connecté..


Si nous courons cette page et allons à la / Compte / ChangeEmail action, nous voyons maintenant que nous n'avons actuellement pas d'email. Mais nous avons une zone de texte et un bouton que nous pouvons utiliser pour corriger cela. Cependant, nous devons d’abord créer l’action à exécuter lorsque le formulaire de cette page est soumis..

[HttpPost] public ActionResult ChangeEmail (modèle ChangeEmailModel) chaîne nom_utilisateur = WebSecurity.CurrentUserName; using (UsersContext db = new UsersContext ()) UserProfile user = db.UserProfiles.FirstOrDefault (u => u.NomUtilisateur.ToLower () == nomutilisateur); user.EmailAddress = model.NewEmail; db.SaveChanges ();  // Et pour vérifier le changement, récupérez l'email du profil ChangeEmailModel newModel = new ChangeEmailModel (); using (UsersContext db = new UsersContext ()) UserProfile user = db.UserProfiles.FirstOrDefault (u => u.NomUtilisateur.ToLower () == nomutilisateur); newModel.CurrentEmail = user.EmailAddress;  return View (newModel); 

Après avoir effectué ce changement, lancez le site Web et accédez à nouveau à / Compte / ChangeEmail action que nous venons de créer. Vous pouvez maintenant entrer une nouvelle adresse e-mail et cliquer sur le bouton Changer l'e-mail bouton et voir que l'adresse email sera mise à jour.


Attaquer le site

Comme indiqué, notre application est vulnérable à une attaque par falsification de requêtes intersites. Ajoutons une page Web pour voir cette attaque en action. Nous allons ajouter une page sur le site Web qui modifiera le courrier électronique en une valeur différente. dans le HomeController.cs fichier, nous allons ajouter une nouvelle action nommée AttackForm.

public ActionResult AttackForm () return View (); 

Nous allons également ajouter une vue pour ce nommé AttackForm.aspx sous le / Vues / Accueil dossier. Ça devrait ressembler à ça:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage"%>  Formulaire d'attaque   

Formulaire d'attaque

Cette page a une forme cachée, pour vous attaquer, en changeant votre email:

Notre page annonce utilement sa mauvaise intention, ce qui, bien sûr, ne serait pas une véritable attaque. Cette page contient un formulaire masqué qui ne sera pas visible pour l'utilisateur. Il utilise ensuite Javascript pour soumettre automatiquement ce formulaire lorsque la page est chargée..


Si vous exécutez à nouveau le site et accédez au / Accueil / AttackForm page, vous verrez qu'il se charge très bien, mais sans aucune indication extérieure que tout est arrivé. Si vous allez maintenant au / Compte / ChangeEmail page cependant, vous verrez que votre email a été changé en [email protected]. Ici, bien sûr, nous mettons cela intentionnellement en évidence, mais lors d'une véritable attaque, vous pourriez ne pas remarquer que votre email a été modifié..


Atténuation de la falsification de requêtes intersites

Il existe deux moyens principaux d'atténuer ce type d'attaque. Tout d'abord, nous pouvons vérifier le renvoi d'où provient la demande Web. Cela devrait indiquer à l'application qu'une soumission de formulaire ne provient pas de notre serveur. Cela a deux problèmes cependant. De nombreux serveurs proxy suppriment ces informations de renvoi, soit intentionnellement pour protéger la confidentialité, soit en tant qu'effet secondaire, ce qui signifie qu'une requête légitime ne peut pas contenir ces informations. Il est également possible pour un attaquant de simuler le renvoi, bien que cela augmente la complexité de l'attaque..

La méthode la plus efficace consiste à exiger qu'un jeton spécifique à l'utilisateur existe pour chaque soumission de formulaire. La valeur de ce jeton doit être générée de manière aléatoire chaque fois que le formulaire est créé et le formulaire n'est accepté que si le jeton est inclus. Si le jeton est manquant ou si une valeur différente est incluse, nous n'autorisons pas la soumission du formulaire. Cette valeur peut être stockée dans l'état de la session de l'utilisateur ou dans un cookie pour nous permettre de vérifier la valeur lors de l'envoi du formulaire..

ASP.NET facilite ce processus, car le support CSRF est intégré. Pour l'utiliser, nous n'avons besoin que de deux modifications sur notre site Web..


Résoudre le problème

Tout d'abord, nous devons ajouter le jeton unique au formulaire pour modifier le courrier électronique de l'utilisateur lorsque nous l'afficherons. Mettre à jour le formulaire dans le ChangeEmail.aspx voir sous / Compte / ChangeForm:

<% using(Html.BeginForm())  %> <%: Html.AntiForgeryToken() %> <%: Html.TextBoxFor(t=>t.NewEmail)%>  <%  %>

Cette nouvelle ligne: <%: Html.AntiForgeryToken() %> indique à ASP.NET de générer un jeton et de le placer en tant que champ masqué dans le formulaire. En outre, le framework gère le placement dans un autre emplacement où l'application peut y accéder ultérieurement pour le vérifier..

Si nous chargeons maintenant la page et examinons la source, nous verrons cette nouvelle ligne, sous la forme, restituée au navigateur. Ceci est notre gage:

Nous devons également modifier notre action pour lui faire savoir que nous avons ajouté ce jeton et qu'il devrait vérifier le jeton avant d'accepter le formulaire envoyé..

Encore une fois, cela est simple dans ASP.NET MVC. En haut de l’action que nous avons créée pour gérer le formulaire posté, celle avec le [HttpPost] attribut ajouté, nous ajouterons un autre attribut nommé [ValidateAntiForgeryToken]. Cela donne le début de notre action maintenant comme ceci:

 [HttpPost] [ValidateAntiForgeryToken] public ActionResult ChangeEmail (modèle ChangeEmailModel) string nom_utilisateur = WebSecurity.CurrentUserName; * reste de la fonction omis *

Testons ceci. D'abord aller au / Compte / ChangeEmail page et restaurez l’email de votre compte avec une valeur connue. Ensuite, nous pouvons revenir à la / Accueil / AttackForm page et encore le code d'attaque tente de changer notre email. Si vous revenez à la / Compte / ChangeEmail page encore, cette fois, vous verrez que votre email précédemment entré est toujours sûr et intact. Les modifications que nous avons apportées à notre formulaire et à nos actions ont protégé cette page de l'attaque..

Si vous regardiez le formulaire d’attaque directement (facilement fait en retirant le