[ASP .NET/IIS] Comprendre le concept d’identité, privilège et d’authentification utilisateur sous IIS et ASP .NET

Après divers audits chez des clients concernant des applications ASP .NET, je me suis rendu compte, que bon nombre de développeurs (et d’administrateurs systèmes) n’avait aucune connaissance (ou alors très limitée) sur la sécurité et l’authentification concernant les applications ASP .NET fonctionnant sous IIS 6.0 ou IIS 7.0. Certains n’hésitent pas à donner des droits administrateurs à leurs applications présentes sur internet, offrant ainsi une porte grande ouverte aux utilisateurs mal intentionnés !

C’est pour ces diverses raisons que je rédige cet article, afin que les développeurs (mais aussi les administrateurs systèmes) puissent mieux appréhender les concepts de base lié à la sécurité et l’authentification des applications ASP .NET sous IIS.

Cet article est divisé en 4 parties :

Cet article est consacré à un environnement sous IIS 7.0 présent sur un serveur Windows 2008 autonome (non inclus dans un domaine Active Directory). Les applications IIS 7.0 fonctionneront uniquement en mode intégré.

Les concepts de base sur les identités

Avant de rentrer dans le vif du sujet, je vous propose de voir (ou de revoir) les concepts de bases concernant la notion d’identité et d’authentification sous Windows.

Les comptes utilisateurs Windows.

Les comptes utilisateurs Windows, comme leur nom l’indique, représente un utilisateur sous l’environnement Windows. Ils possèdent les caractéristiques suivantes :

  • Un nom (par exemple « Gilles.Tourreau »)
  • Un mot de passe (par exemple « MonMotPasse »).
  • Un SID (Identifiant unique du compte).
  • Des privilèges (droits ou autorisations) associés.

Il est possible de regrouper les comptes utilisateurs dans des « groupes ». Comme les comptes utilisateurs, les groupes possèdent un nom, un SID et des privilèges associés. Un groupe peut contenir d’autres groupes. Lorsque l’on associe un privilège à un groupe, c’est tous les utilisateurs et les groupes contenu dans ce dernier qui bénéficie de ce privilège.

Grâce aux comptes utilisateurs, on peut donner une identité à certains objets de Windows (par exemple les processus). Ainsi, lorsque ces objets agissent sur leur environnement, ils utilisent l’identité qui leur a été attribué. Par exemple un processus qui ouvre un fichier en écriture, ne peut le faire qui si l’identité attachée à ce processus dispose des droits nécessaire (en l’occurrence l’accès à l’écriture sur le fichier).

Les privilèges (aussi appelé « droits » ou « autorisations »).

Les privilèges sont tout simplement des autorisations sur une ressource système que l’on accorde à un compte utilisateur. Les réglages de ces privilèges dépendant de la nature de la ressource à protéger. Les privilèges permettent à des objets disposant d’une identité, de pouvoir ou non utiliser une ressource. Par exemple, l’accès à un fichier ou l’accès à une base de données sur SQL Server.

Voici un exemple du réglage des droits utilisateurs sur un fichier :

Réglage des droits utilisateurs pour un dossier

Réglage des droits utilisateurs pour un dossier

Voici un autre exemple de réglage des droits utilisateurs :

Réglage des droits utilisateurs

Réglage des droits utilisateurs

Comme vous le constatez dans les 2 captures d’écrans précédentes, les privilèges se paramètre différemment suivant la nature de la ressource à protéger.

Le concept du moindre privilège

Le concept du moindre privilège consiste à donner à chaque utilisateur des accès UNIQUEMENT aux ressources dont il a besoin !

Il ne faut surtout pas « masquer les privilèges » des utilisateurs ! Le concept du masquage des privilèges consiste à donner des privilèges importants à l’utilisateur, tout en lui « masquant » dans l’application certains de ses privilèges.

Par exemple, si on donne un accès complet sur un site web à un utilisateur (partie visiteur et partie administration du site). Mais en réalité, on ne veut pas que cet utilisateur ai accès à la partie administration du site. Dans ce cas, il ne faut pas lui cacher le lien « Administration » permettant d’accéder à la partie administrative du site. En effet, il est très simple pour un utilisateur (le plus souvent mal intentionné) de découvrir des URL d’administration d’un site web. Il faut plutôt lui interdire explicitement l’accès à la partie administration.

Les comptes utilisateurs prédéfinis

Ce sont des comptes qui sont crées lors de l’installation de Windows et intégré au système. On ne peut pas les supprimer ou les modifier (changer de nom) et ils ne possèdent pas de mot de passe. Ces comptes dispose d’un SID unique (le même d’un ordinateur à un autre). Comme ils ont le même SID, même si leur nom est différent d’une langue à une autre (par exemple, en Français le compte « Service Réseau » s’appelle en Anglais « Network Service »), ils représentent le même compte utilisateur.

Certains comptes sont spéciaux et c’est Windows qui gère l’appartenance à ses groupes automatique. Un exemple d’un tel groupe est le groupe Tout le monde. Ce groupe représente tous les comptes utilisateurs présents sur la machine. Comme Windows gère automatiquement l’appartenance, ce n’est pas à l’administrateur système d’associer explicitement les nouveaux comptes utilisateur à ce groupe lors de leur création.

D’autres comptes tel que Service réseau et Service local sont des comptes utilisateurs dont leur privilège sont automatiquement réglés pour permettre aux services Windows de fonctionner en local sur la machine ou à travers le réseau.

Dans tous les cas, il est possible de changer les privilèges de ces comptes (Ce qui nous le verrons, est fortement DECONSEILLE !).

La liste de tous ces comptes (ainsi que leur SID associé) est disponible sur la KB243330 de Microsft.

Les processus

Les processus sont des instances d’une application en mémoire. Chaque processus Windows s’exécute sur un compte utilisateur. (C’est une phrase à retenir !) On dit alors que le compte utilisateur associé à ce processus représente l’identité de ce dernier. Lorsque l’on lance un programme, on doit toujours spécifier le compte utilisateur Windows et le mot de passe associé sur lequel le processus crée doit s’exécuter. Si on ne fourni pas ces informations, le compte utilisateur du processus qui a crée le nouveau processus sera utilisé.

Un processus est une instance d’un programme, c’est-à-dire un du code qui s’exécute. Si on prend l’exemple d’une application .NET, le code qui est exécuté est un ensemble de méthodes (par exemple File.Open()). Lors de l’exécution d’une telle méthode, le processus demandera l’ouverture d’un fichier à Windows en fournissant comme identité le compte utilisateur sous lequel l’application s’exécute. Windows vérifiera si ce compte utilisateur dispose des droits nécessaires pour accéder à ce fichier.

Exemple d'accès à un fichier par le processus "MonApp.exe"

Exemple d'accès à un fichier par le processus "MonApp.exe"

Le schéma précédent montre un processus d’une application (MonApp.exe) qui s’exécute sous l’identité Gilles. Ce schéma montre que l’appel à File.Open() fonctionne sur un fichier dont Gilles disposent les droits d’accès (En lecture et écriture). Par contre, ce processus (avec l’identité Gilles) ne peut accéder au fichier dont seul Claude dispose des droits de lecture et écriture.

REMARQUE : Lorsque vous entendez la phrase (que l’on retrouve sur plusieurs forums, y compris dans mes posts…) : « L’application doit avoir les droits sur tel fichier« . Ce n’est pas l’application qui doit avoir le droit sur tel fichier, mais un processus (instance) de cette application ! Comme une application, peut avoir plusieurs instances (processus), elle peut donc s’exécuter sur différents comptes utilisateurs.

L’emprunt d’identité

Fonctionnalité méconnu (ou incomprise) de Windows, mais très utile dans les applications ASP .NET. Posons le problème suivant :

Nous avons une application qui fonctionne sur un compte utilisateur « MonApp », des utilisateurs déclenchent une action sur cette application qui va automatiquement lire un fichier dans un répertoire.

Accès en lecture/écriture à un fichier pour deux utilisateurs ayant des droits différents

Accès en lecture/écriture à un fichier pour deux utilisateurs ayant des droits différents

Bien entendu cela est possible uniquement si le compte « MonApp » dispose des droits suffisants sur ce fichier.

Certains utilisateurs importants (un administrateur par exemple), souhaite pouvoir modifier ce fichier à travers cette application. Pour cela tout bon développeur modifie son application et produit ce petit bout de code :

if (UtilisateurEstAdministrateur == true)
{
	ModifierFichier() ;
}
else
{
	LireFichier() ;
}

Vous recompilez et déployez l’application, l’administrateur se connecte sur l’application et boum ! Windows l’insulte avec ce fameux code d’erreur « n°5 », lui indiquant qu’il n’a pas les droits nécessaires pour ouvrir ce fichier ! (Un comble pour un administrateur qui a d’habitude tous les droits ! 😉 ).

Bien évidemment, vous comprenez d’ou vient le problème : Il suffit de modifier les droits sur le fichier pour autoriser le compte utilisateur « MonApp » en écriture. En procédant ainsi, vous résolvez le problème, mais votre fichier peut-être potentiellement modifié par un utilisateur qui arriverait à trouver une faille dans votre application. Si cet utilisateur trouve le moyen de changer la valeur de la variable « UtilisateurEstAdministrateur » du code précédent, il peut donc facilement accéder en écriture au fichier !

La solution pour remédier à ce problème est l’emprunt d’identité, le principe est le suivant :

Une application emprunte l’identité d’un autre compte pendant un certain temps (le plus court possible de préférence !). L’emprunt de cette identité permet bien évidemment à une application, d’accéder à une ressource dont elle ne disposerait pas d’un accès sur celle-ci en temps normal.

Exemple d'emprunt d'identité

Exemple d'emprunt d'identité

Si l’on procède ainsi, il suffit alors dans notre exemple, de donner les droits de lecture à tout le monde et les droits lecture/écriture aux administrateurs sur le fichier. Ainsi, si un utilisateur (non administrateur) trouve une faille dans notre application et l’exploite, il ne pourra pas accéder au fichier en écriture.

Contrairement aux idées reçues, l’emprunt d’identité n’est pas un mécanisme complexe à mettre en oeuvre. En .NET, il suffit d’utiliser une méthode appellée WindowsIdentity.Impersonate(). Pour revenir à l’identité précédente il suffit de faire un WindowsImpersonationContext.Undo() sur le WindowsImpersonationContext renvoyée par la méthode Impersonate() invoquée précédemment.

L’authentification

Concept bien connu dans les développements informatique et présent dans de nombreuses applications informatiques et surtout dans les systèmes d’exploitation tel que Windows.

L’authentification est le processus qui permet de valider l’identité d’un utilisateur. Contrairement à ce que beaucoup de personne peuvent penser, cela n’a aucun rapport avec l’identité sous lequel le processus d’exécute.

Exemple de processus d'authentification

Exemple de processus d'authentification

Il est très facile de réaliser un mécanisme d’authentification dans une application. Voici une description très rapide :

  • Il faut d’abord avoir un emplacement de stockage (fichier, base de données,…etc) contenant les logins et les mots de passe des utilisateurs.
  • On appelle le plus souvent une méthode (ou fonction) permettant d’authentifier un utilisateur, en envoyant bien évidemment en paramètre le login et le mot de passe de l’utilisateur.
  • En cas de succès cette méthode nous renvoie le plus souvent un jeton (ou ticket) qui est à conserver tout le long de l’utilisation de l’application. C’est grâce à ce jeton, que l’application sait que l’utilisateur qui utilise actuellement l’application, est authentifié.
  • Le jeton contient dès fois, des informations concernant les privilèges (ou les rôles) que dispose un utilisateur. Même si l’utilisateur est authentifié (possède une identité valide), il faut quand même s’assurer que ce dernier dispose des droits nécessaires pour réaliser une opération particulière.

Faire confiance aux éditeurs dont le métier est la sécurité !

Une petite remarque avant d’attaquer la partie consacrée à ASP .NET et IIS :

J’ai rencontré énormément d’applications, où les développeurs n’hésitent pas à créer leur propre mécanisme d’authentification et de gestion de la sécurité. (Le plus souvent ils le font par plaisir, d’autres parce qu’ils sont des développeurs « du Dimanche » et n’y connaissent rien en informatique…). Il faut absolument éviter ce genre de développement si on ne dispose pas d’une expérience et d’une forte connaissance dans ce domaine !

Utilisez au maximum les mécanismes de sécurité et d’authentification d’éditeur dont leur métier est d’offrir ce genre de service. Les éditeurs des systèmes d’exploitation en sont des exemples ! Le métier de Microsoft (plus particulièrement la division qui se charge de la conception de Windows) est de fournir une application permettant d’offrir des services que les développeurs et utilisateurs puissent utiliser (Gestion des fichiers, IHM,…, et surtout la sécurité). Même si lors du « Patch Tuesday », des composants de Windows sont mis à jour (le bogue zéro n’existe pas !), Microsoft (et autres acteurs dans le domaine de la sécurité) doit rester vis à vis de vous, un concepteur offrant des services permettant de gérer la sécurité de vos applications.

Si malgré tout, vous vous opposez à cette vision, dans ce cas continuez dans la même voie en implémentant votre propre système de gestion de fichiers, votre propre gestion des périphériques, votre propre base de données,…

Architecture et concepts de base sur la sécurité d’IIS et d’ASP .NET

Cette partie est entièrement consacrée sur les concepts de base de la sécurité au niveau d’IIS et d’ASP .NET.

IIS un service Windows qui démarre un simple processus d’écoute !

IIS est un serveur web, plus techniquement c’est un service Windows qui tourne par défaut sous le compte utilisateur Service Local. Ce service va crée automatiquement un autre processus (son doux nom est w3wp.exe) qui passe sont temps à écouter des requêtes (HTTP par exemple), à les analyser et à répondre au client (un rendu d’une page HTML par exemple). Le rendu HTML sur un serveur consiste le plus souvent, à lire un fichier .html sur un serveur et à le rendre au client. Bien évidemment, pour que cette action soit possible, il faut que le processus d’IIS (w3wp.exe) ait les droits nécessaires pour accéder à la page html en question.

Un processus IIS traite une requête qui est destiné à un ou plusieurs sites web !

Lors de l’arrêt de IIS, c’est le service IIS et le processus crée qui sont arrêtés.

ASP .NET un « module » d’IIS.

ASP .NET est en fait un « plugin » d’IIS 6.0 (il est entièrement intégré dans IIS pour la version 7.0). Ces plugins sont communément appelés « modules ISAPI » (Internet Server Application Programming Interface). Le fonctionnement de ces modules est le suivant :

Lorsqu’IIS reçoit une requête d’un client, sur une condition particulière (la page demandée est une page .aspx par exemple), il transfère la requête au plugin (à ASP .NET par exemple) et attend que ce dernier est fini le traitement de la page. Une fois le traitement de la page terminé, c’est à dire le code HTML généré par ASP .NET, est rendu au client. Ce principe est le même pour d’autres modules ISAPI, tel que PHP…

Pipeline d'exécution d'une requête ASP .NET dans IIS

Pipeline d'exécution d'une requête ASP .NET dans IIS

Le schéma précédemment montre très simplement l’ordre d’exécution d’une requête HTTP. Bien évidement, il est important de noter que si le traitement est interrompu (volontairement ou à cause d’une erreur) par IIS, elle ne sera en aucun cas transmisse à ASP .NET ! Cela peut vous paraître bête à première vue, cela l’est beaucoup moins lorsque que l’on parle d’authentification IIS couplé avec une application ASP .NET. En effet, IIS possède ses propres méthodes d’authentification et ASP .NET les siennes. Si vous souhaitez utiliser une authentification ASP .NET par formulaire, que vous gérez vous même avec votre propre base de données, il est nécessaire que IIS laisse passer le traitement de la requête sans contrôler l’authentification de celle-ci. Cela implique le plus souvent l’utilisation d’une authentification anonyme au niveau d’IIS et donc la porte ouverte à tout le monde dans votre application ASP .NET !

Lorsque vous exécutez le traitement d’une page ASP .NET, le processus IIS exécute une dll (aspnet_isapi.dll installé par le .NET Framework). L’exécution de cette dll (et donc du code), se fait sous le même compte utilisateur que le processus IIS. Ainsi, si vous devez donner des droits utilisateurs à votre application ASP .NET, vous devez modifier les droits du compte utilisateur sous lequel tourne le processus IIS.

L’identité utilisateur et l’identité processus.

Comme je l’ai expliqué dans la partie consacré à l’authentification, l’identité utilisateur et l’identité processus n’ont rien à voir ensemble. Ces deux informations sont distinctes et peuvent être récupérée, dans une application ASP .NET, via les méthodes/propriétés .NET suivantes :

  • Identité du processus : System.Security.Principal.WindowsIdentity.GetCurrent()
  • Identité de l’utilisateur : System.Web.HttpContext.User (Pour obtenir le contexte courant : System.Web.HttpContext.Current)

Voici un exemple du résultat affiché dans une application ASP .NET avec l’authentification Windows.

Résultat affiché dans une application ASP .NET avec l'authentification Windows

Résultat affiché dans une application ASP .NET avec l'authentification Windows

Les pools IIS

Le fait qu’IIS soit un processus unique était le fonctionnement d’IIS 5.0 (Inclus avec Windows 2000). Si vous devez avoir plus d’une application ASP .NET fonctionnant sur le même serveur web, cela risque d’engendrer un problème de sécurité.

En effet, toutes vos applications ASP .NET s’exécute sur le même compte utilisateur et donc avec le même niveau de sécurité.

Processus IIS exécutant 3 applications ASP .NET

Processus IIS exécutant 3 applications ASP .NET

Ainsi, il est facile à une application d’avoir accès aux ressources des autres applications présentes sur le même serveur IIS.

Attaque possible d'une base de données à travers une autre application ASP .NET

Attaque possible d'une base de données à travers une autre application ASP .NET

Pour palier à ce problème, Microsoft a introduit dans IIS 6.0 le concept de pool d’applications. Cette fonctionnalité consiste à regrouper des sites web et à les faire fonctionner sur un même compte utilisateur (identité). Plus techniquement, un pool IIS correspond tout simplement à un nouveau processus IIS. Les pools permettent donc d’avoir des processus IIS qui tournent sur des comptes d’utilisateurs différents.

3 applications ASP .NET fonctionnant sur 3 pools IIS différents.

3 applications ASP .NET fonctionnant sur 3 pools IIS différents.

Voici ce que l’on peut apercevoir dans le gestionnaire des tâches lorsque 3 pools IIS sont activés.

Pool IIS visibles dans le gestionnaire de tâches

Pool IIS visibles dans le gestionnaire de tâches

Comme vous pouvez le constater, 3 processus sont exécutés indépendamment et disposent d’une identité qui peut être différente.

Par défaut, les pools IIS (version 6.0 et 7.0) fonctionnent sur le compte prédéfini Service Réseau.

Les entités de sécurité d’IIS.

Sous IIS 6.0, le programme d’installation crée 1 compte utilisateur appelé IUSR_NomOrdinateur (où NomOrdinateur est le nom de votre ordinateur) et un groupe appelé IIS_WPG.

L’utilisateur IUSR_NomOrdinateur correspond aux utilisateurs anonymes. Lorsque les utilisateurs se connectent sur votre serveur web sans s’authentifier (et si vous leur donnez le droit), ils sont automatiquement authentifiés avec ce compte. (La section suivante explique en détail ce fonctionnement).

Le groupe IIS_WPG est un groupe qui contient (et doit contenir) tous les comptes utilisateurs utilisés par les pools IIS. Lors de l’installation d’IIS, ce groupe est configuré pour donner les droits nécessaires aux comptes de service des pools IIS. Vous devez donc ajouter vos propres comptes utilisateurs dans ce groupe, si vous décidez de faire fonctionner des pools IIS avec ces comptes utilisateurs.

Sous IIS 7.0, ces entités de sécurité sont devenues des comptes intégrés à Windows, permettant ainsi d’utiliser le même compte utilisateur (SID identique) d’un ordinateur à un autre. Leur fonctionnement reste le même que sous IIS 6.0.

Les nouveaux noms de ces comptes sont :

  • IUSR qui remplace le compte IUSR_NomOrdinateur.
  • IIS_IUSRS qui remplace le groupe IIS_WPG.

Microsoft a apporté un petit plus en ce qui concerne le groupe IIS_IUSRS (ex IIS-WPG), en effet, lorsque l’on spécifie un compte utilisateur à un pool IIS, il n’est plus nécessaire d’ajouter le compte au groupe IIS_IUSRS, IIS le fait automatiquement.

L’authentification dans IIS

Lorsqu’un utilisateur se connecte sur votre site, il est important de connaitre son identité. IIS propose plusieurs modes d’authentifications et dont les modes les plus importants sont :

  • L’authentification anonyme.
  • L’authentification Windows.
  • L’emprunt d’identité (couplée avec les méthodes précédentes).

Il existe d’autres types d’authentifications, mais qui ne seront pas expliqués dans cet article.

L’authentification anonyme

L’authentification anonyme consiste tout simplement à associer tous les utilisateurs non authentifiés à un compte utilisateur particulier (par exemple le compte IUSR dans IIS 7.0). Il est ainsi possible d’utiliser ce compte utilisateur afin de d’octroyer (ou de refuser) des privilèges sur des ressources.

Sous IIS 7.0, il est possible d’indiquer que le compte anonyme est celui d’un compte particulier ou celui du pool d’application. Dans le cas où on utilise un compte utilisateur spécifique, IIS réalise un emprunt d’identité de ce compte.

L’authentification Windows

Ce type d’authentification consiste à demander à l’utilisateur de saisir un login et mot de passe Windows valide et présent sur l’environnement ou s’exécute IIS. Lorsque l’utilisateur est authentifié.

L’authentification Windows, permet de gérer les comptes à travers l’interface de gestion des groupes et utilisateurs de Windows (ou l’annuaire dans un domaine Active Directory).

L’emprunt d’identité

Si vous utilisez l’une des authentifications précédentes, cela vous permet d’obtenir uniquement comme information l’identité des utilisateurs connectés sur le site. Dans le cas de l’authentification Windows, cela vous permet de valider les utilisateurs qui peuvent se connecter à votre site internet.

Du point de vue Windows, les droits appliqués seront ceux du pool IIS et nom de l’utilisateur authentifié. Pour utiliser les privilèges de l’utilisateur authentifié, vous devez activer l’emprunt d’identité.

L’authentification dans ASP .NET

Le traitement d’une requête HTTP par ASP .NET a lieu uniquement si l’authentification d’une requête IIS a réussi. Dans le cas contraire, la requête ne sera ni envoyée, ni traitée par ASP .NET.

L’authentification par formulaire (« Forms »)

ASP .NET dispose d’une méthode d’authentification appelé « Forms » (en français, authentification par formulaire). Le concept est tout simple : l’authentification est entièrement gérée par ASP .NET. Ce mode d’authentification se charge de rediriger l’utilisateur si nécessaire vers une page d’authentification, de contrôler la validité les logins (et mots de passe associés) à partir d’un emplacement de stockage (fichier de configuration, base de données,…etc).

L’authentification par formulaire permet de s’appuyer sur des comptes utilisateurs non Windows (présents dans une base de données). Cela est utile lorsqu’il est impossible de créer des comptes utilisateurs Windows (par exemple chez des hébergeurs mutualisés). De plus, ce genre d’authentification permet de s’appuyer sur une API robuste (développé par Microsoft) et peu être facilement extensible.

Comme ce mode d’authentification n’utilise pas les comptes utilisateurs Windows, l’inconvénient majeur de ce genre d’authentification est la non utilisation des contrôles d’accès aux ressources par Windows. Les privilèges d’accès aux ressources doivent être configuré pour le compte de service sous lequel le pool IIS s’exécute.

L’authentification Windows

Ce n’est pas ASP .NET qui gère cette authentification. Cela indique tout simplement que l’authentification est gérée par IIS. Ce réglage à une importance au niveau de la propriété HttpContext.User : Il permet d’indiquer à ASP .NET de récupérer l’utilisateur Windows actuellement authentifier et de le placer dans cette propriété. Ainsi, vous pouvez utiliser cette information dans vos pages ASP .NET.

L’authentification personnalisée

Comme je l’ai évoqué précédemment, ce genre d’authentification est pour moi à proscrire, sauf si vous faites appel à des spécialistes en sécurité. Bien évidement, avec ce genre d’authentification vous êtes libre de faire votre propre logique d’authentification. Mais faites attention, car tous les problèmes de sécurité reposent sur votre application !

Remarques concernant l’emprunt d’identité sous IIS 7.0 en mode intégré

Sous IIS 7.0, lorsque le mode intégré (au niveau du pipeline de traitement) est utilisé pour les applications ASP .NET, l’emprunt d’identité a lieu uniquement après l’étape AuthenticateRequest. Cela implique que vos fichiers de votre application doivent être accessibles par l’identité du pool d’application (avant l’étape AuthenticateRequest) et par l’identité emprunté (après l’étape AuthenticateRequest).

Si vous activez l’emprunt d’identité dans votre application, empruntant l’identité de l’utilisateur authentifié, vous obtiendrez l’erreur suivante au niveau d’IIS :

Message d'erreur de IIS 7.0 avec l'emprunt d'identité en mode intégré

Message d'erreur de IIS 7.0 avec l'emprunt d'identité en mode intégré

Pour ne plus avoir ce message d’erreur, vous devez ajouter ce fragment XML dans votre fichier web.config de votre application ASP .NET :

&lt;system.webServer&gt;<br />
    &lt;validation validateIntegratedModeConfiguration=&quot;false&quot; /&gt;<br />
&lt;/system.webServer&gt;

Le choix du compte utilisateur d’une application ASP .NET

Maintenant que nous avons vu tous les concepts de base lié à l’authentification et l’identité des applications, voyons maintenant de façon théorique les concepts de sécurité à appliquer sur une application ASP .NET.

Par défaut, beaucoup de personnes laissent les pools IIS fonctionner sur le compte intégré « Service réseau ». C’est un choix qui peut sembler correct, car ce compte procure les droits nécessaires à l’exécution d’un site sous IIS. Mais, c’est un compte qui est utilisé par d’autres applications Windows et en particulier les services.

Exemple d'une liste de services Windows avec le compte utilisateur associé.

Exemple d'une liste de services Windows avec le compte utilisateur associé.

Or, il arrive parfois que l’on est tenté d’attribuer un privilège à ce compte spécifiquement pour une application particulière. Cela ne pose pas de problème en soi au niveau du fonctionnement des applications utilisant ce compte utilisateur, mais procure un privilège qui est non nécessaire aux autres applications.

Voici un exemple qui illustre ce problème :

Nom de l’application (processus) Identité du processus Droits (privilèges) accordés
Pool IIS – 1 (w3wp.exe) Service réseau Privilège X
Pool IIS – 2 (w3wp.exe) Utilisateur1 Privilège Y
Appel de procédure distante (Service Windows) Service réseau Privilège X

Comme l’application « Pool IIS – «  » et le service « Appel de procédure distance (Service Windows) » fonctionne sous le même compte utilisateur, ils disposent des mêmes privilèges. Pour continuer à illustrer le problème, voici maintenant ce que l’on rencontre fréquemment lors de la mise en production d’une application ASP .NET (et le mauvais réflexe utilisé pour pallier au problème…) :

L’administrateur système se rend compte que l’application se trouvant dans le « Pool IIS – 1 » ne peut pas se connecter au serveur de base de données. Pas de problème ! Il suffit tout simplement d’ajouter le compte « Service réseau » dans la liste des utilisateurs autorisés à se connecter sur le serveur de base de données. Voici maintenant le tableau qui résume les privilèges des différents processus du précédent exemple :

Nom de l’application (processus) Identité du processus Droits (privilèges) accordés
Pool IIS – 1 (w3wp.exe) Service réseau Privilège X
Se connecter au serveur de base de données
Pool IIS – 2 (w3wp.exe) Utilisateur1 Privilège Y
Appel de procédure distante (Service Windows) Service réseau Privilège X
Se connecter au serveur de base de données

Vous vous rendez compte que maintenant le service d’appel de procédure distante dispose d’un privilège supplémentaire qui ne le lui est pas requis ! Comme expliqué précédemment, cela ne pose aucun problème au niveau du fonctionnement du service. Mais dans le cas où un utilisateur mal intentionné trouve une faille dans le service d’appel de procédure distante afin d’exécuter du code malveillant, il peut grâce à ce code, fonctionnant sous le compte « Service réseau », se connecter au serveur de base de données !

Pour éviter ces problèmes de sécurité il est toujours recommandé d’utiliser un compte utilisateur spécifique pour une application ASP .NET.

Si votre application, doit se connecter à une ressource externe, par exemple un serveur de base de données SQL Server, c’est ce compte qu’il faudra ajouter dans les connexions autorisées afin d’accéder à la base de données. Il en est de même pour toutes les autres ressources (fichiers,…etc).

Il est intéressant de noter que la création d’un compte utilisateur dédié à une application permet aussi de :

  • Simplifier les audits de sécurité. En effet, comme vous savez que ce compte est dédié à votre application ASP .NET, vous pouvez aisément contrôler les ressources que votre application utilise ou ne devrait pas utiliser.
Tiens ! Un service qui ouvert une session... Oui mais lequel... ?

Tiens ! Un service qui ouvert une session... Oui mais lequel... ?

  • D’activer ou désactiver l’application dans son ensemble. En effet, lorsque vous désactivez un compte utilisateur, au niveau de l’environnement Windows, et si ce dernier associé à une application ASP .NET, alors le pool IIS ne fonctionnera plus, mais aussi l’accès aux ressources qui autorise ce compte utilisateur (par exemple SQL Server).

De manière générale, les comptes utilisateurs dédiés au fonctionnement des applications de type « service » (c’est à dire autonome et sans interaction avec l’utilisateur), sont appelés des comptes de service.

Dans certains cas, l’emprunt d’identité est nécessaire…

L’utilisation d’un compte utilisateur dédié à une application pose problème si vous souhaitez accéder à une même ressource avec des droits différents en fonction des utilisateurs. A noter que le problème est le même si vous utilisez un compte prédéfini tel que « Service réseau ».

Prenons un exemple : vous avez une application ASP .NET qui propose de consulter un catalogue de tondeuse à gazon. Bien évidemment, les visiteurs ont un accès en lecture seul à ce catalogue (et donc à la base de données). Mais certains utilisateurs (les responsables du catalogue) doivent avoir le droit de modifier ce catalogue. Comment bien gérer l’authentification dans ce cas ?

Voici les mauvaises configurations possibles avec leurs explications (que j’ai rencontrées personnellement en réalisant des audits) :

  • Attribution du droit de lecture/écriture sur la base de données pour le compte « Service réseau » (L’application ASP .NET tourne sur un pool avec le compte de service « Service Réseau »). Explication : Attribuer le droit de lecture/écriture sur la base de données pour le compte « Service réseau », permet à un utilisateur mal intentionné qui trouverait une faille dans votre site ASP .NET de modifier votre catalogue. De plus, comme il a été expliqué précédemment, les autres applications fonctionnant sur le compte « Service réseau » et peuvent donc accéder en écriture à la base de données. Un utilisateur mal intentionné peut donc accéder à votre base de données en passant par une faille qui se trouverait sur l’une de ces applications.
  • Faire fonctionner le pool IIS avec un compte administrateur. Explication : Aussi bizarre que cela puisse paraitre, ce cas est le plus fréquent !!! Bien évidemment cette configuration est à proscrire ! (Et d’ailleurs une excellente preuve pour licencier l’administrateur système). Si un utilisateur mal intentionné trouve une faille dans votre site internet, c’est la porte ouverte à l’accès complet des ressources de votre système (ordinateur ou réseau complet !).
  • Faire fonctionner le pool IIS avec un compte utilisateur dédié. C’est une bonne idée, mais elle nous oblige à donner les droits d’écriture à ce compte dans la base de données (et donc encore un accès potentiel en écriture par un utilisateur mal intentionné en cas de présence d’une faille sur votre application ASP .NET).

La réponse à ce problème est en parti résolue dans la troisième idée. Il faut juste utiliser une fonctionnalité en plus : l’emprunt d’identité.

Voilà donc la configuration idéale (pour cet exemple) qui utilise l’emprunt d’identité :

  • On crée un compte utilisateur dédié à cette application (c’est donc le compte de service du pool où s’exécute votre application ASP .NET).
  • Ce compte possède les droits de lecture seulement à la base de données (réglage au niveau de SQL Server).
  • On active l’emprunt d’identité au niveau du site et l’authentification Windows dans la partie du site pour mettre à jour le catalogue.
  • On autorise les utilisateurs qui ont le droit de mettre à jour le catalogue des tondeuses dans SQL Server.

Que faire s’il est impossible d’utiliser l’emprunt d’identité ? (Authentification Windows désactivée).

Dans certaines applications ASP .NET, si vous ne pouvez pas utiliser l’emprunt d’identité car vous ne pouvez pas pour diverses raisons, utiliser l’authentification Windows. Il vous sera difficile de sécuriser au maximum votre application. Surtout si les privilèges des utilisateurs sont très différents d’un compte à un autre.

Dans ce cas, il est bien évident qu’il faille toujours utiliser un compte utilisateur dédié à l’application, mais vous serez obligé de donner des droits « importants » à ce compte sur les ressources utilisées par cette dernière. Par exemple, si certains utilisateurs peuvent consulter une table d’une base de données et d’autres modifier son contenu, il vous faudra octroyer le droit de lecture/ériture sur cette dernière pour le compte de service de l’application.

Serveur IIS contenant d’énormément de site web.

Si on se place dans le contexte d’un serveur IIS disposant de 30 sites webs, certains diront qu’il est très difficile de gérer les 30 comptes de services associés aux différents pools IIS. Pour pallier à ce problème, rien ne vous empêche de créer des groupes de sécurité Windows afin d’y regrouper plusieurs comptes de service. Ainsi, vous pouvez aisément octroyer à ce groupe des droits sur une ressource. Attention, cependant à ne pas reproduire le problème que l’on a évoqué plus haut concernant l’ajout d’un privilège à un ensemble d’application.

La règle « 1 compte utilisateur = 1 pool IIS » n’est pas une obligation. Rien ne vous empêche de regrouper des applications ASP .NET dans le même pool. Par exemple celles qui accèdent à la même base de données. Faites cependant attention le jour où vous décidez d’octroyer un droit supplémentaire au compte utilisateur associé à ce pool !

Quand utiliser les comptes prédéfinis dans les applications ASP .NET ?

La réponse absolue : JAMAIS ! Ces comptes, sont dédiés à Windows et vous ne devez en aucun cas (où de manière très limité) toucher aux privilèges qui leur sont accordés ! De plus, il est a noté que certains comptes prédéfinis disposent de privilèges qui sont le plus souvent non nécessaire à votre application ! Cependant vous pouvez les utiliser si vos applications ne nécessitent aucun privilège particulier (c’est à dire qui n’implique pas la modification des privilèges d’un compte prédéfini).

Mot de passe des comptes de service

Lorsque vous démarrez un processus, Windows a besoin du login et du mot de passe du compte utilisateur sous lequel l’application instanciée (processus) fonctionnera. Bien évidemment, si cette information n’est pas fournie à Windows, le compte utilisateur « ambient » (c’est à dire le compte utilisateur sous lequel fonctionne le processus en cours d’exécution) sera automatiquement utilisé.

La question que l’on peut se poser est comment le service IIS, qui fonctionne par défaut sous le compte Service local, peut-il créer d’autres processus (pool IIS) qui fonctionnerait sous d’autres comptes utilisateurs ? La réponse est simple, les mots de passe sous enregistrées (crypté bien évidemment) en interne dans IIS. Il en est de même avec les services Windows. Ainsi, il est possible de créer et démarrer un processus sous un autre compte utilisateur.

Cela pose un problème particulier en ce qui concerne le changement de mot de passe. Si vous décidez de changer de mot de passe au compte de service, vous devez aussi rechanger le mot de passe qui sont enregistrés ailleurs (dans le gestionnaire de service Windows, dans IIS,…etc).

De manière générale, on ne change jamais les mots de passe des comptes de services et on enlève la fonctionnalité d’expiration du mot de passe. Comme le mot de passe ne change jamais, il est recommandé d’utiliser un mot de passe fort, et même très très fort ! Choisissez par exemple, un mot de passe d’au moins 20 caractères de longueur. La longueur de ce mot de passe peut vous paraitre fastidieux à taper, mais partez du principe que normalement, vous devez saisir ce mot de passe 2 ou 3 fois (au moins une fois lors de la création du compte de service et une autre fois lors de l’enregistrement du mot de passe dans IIS).

Authentification ASP .NET « Forms ».

Si vous envisagez d’utiliser votre propre logique d’authentification dans votre application ASP .NET, il vous faudra configurer IIS de manière à ce qui laisse passer les requêtes HTTP via une authentification anonyme. Cela diminue la sécurité, car il n’est plus possible d’utiliser une authentification Windows et de contrôler de manière plus fine les privilèges permettant l’accès aux ressources.

Faites très attention lorsque vous implémenter votre propre logique d’authentification, tout le poids de la sécurité de votre application repose sur votre code !

Encore une fois, utilisez toujours un compte de service spécifique à votre application et octroyez les privilèges minimum aux ressources que votre application ait besoin.

Configuration d’une application ASP .NET sous IIS 7.0 en matière de sécurité

Dans cette partie nous allons, configurer une application ASP .NET (intitulé CatTond) fonctionnant sur IIS 7.0 en vu de se connecter à une base de données SQL Server. Nous essayerons divers réglages avec leurs explications afin que vous puissiez mieux comprendre leur impact. Nous allons utilisez 3 pages ASP .NET simples (téléchargeable à la fin de l’article) :

  • Default.aspx : Propose un menu permettant d’accéder aux autres pages du site et affiche diverses informations techniques concernant les identités utilisateur et du processus en cous d’exécution.
  • Visiteurs.aspx : Représente la page d’un visiteur de notre site, cette page exécute une requête SQL (SELECT) en vu d’afficher une liste de tondeuse à gazon.
  • Administrateurs.aspx : Représente une page qui exécute une requête SQL (UPDATE) afin d’augmenter les prix des tondeuses.

REMARQUE : Surtout ne prêtez pas attention à la qualité de mon code en ce qui concerne ces pages ASP .NET, ce n’est pas du tout mon style de programmation (surtout en ce qui concerne le SQL Injection !).

Création du site Web IIS

La première étape bien évidemment est de créer un site web IIS et son pool associé. Pour ce faire dans les gestionnaire des services IIS nous faisons un clic droit sur le noeud « Sites » et nous choisissons « Ajouter un site Web… ».

Création d'un site web dans IIS 7.0

Création d'un site web dans IIS 7.0

La fenêtre suivante apparait :

Nom et emplacement du nouveau site web

Nom et emplacement du nouveau site web

Ici on spécifie le nom de l’application et le pool à utiliser. Comme ce dernier est inexistant il sera automatiquement crée. L’emplacement de l’application ASP .NET sera quand à elle présente dans le répertoire (C:\Program Files\P.O.S Informatique\CatTond).

Si on jette un coup d’oeil au niveau du pool crée précédemment :

Pool associé au site web "CatTond"

Pool associé au site web "CatTond"

On se rend compte que par défaut IIS, fait fonctionner le pool IIS sous le compte NetworkService (Service réseau).

Jetons maintenant un petit coup d’oeil sur l’authentification : Pour ce faire, dans le gestionnaire des services IIS, nous sélectionnons le site web crée précédemment et choisissons dans la partie IIS la rubrique Authentification.

Rubrique "Authentification" le console IIS 7.0

Rubrique "Authentification" le console IIS 7.0

Vous constatez que par défaut l’authentification anonyme est activée :

Authentification anonyme activée

Authentification anonyme activée

Cela signifie que n’importe quel utilisateur peut se connecter sur notre application. Sélectionnons maintenant Authentification anonyme et faisons un clic droit afin de choisir l’option Modifier….

Identité des utilisateurs anonymes

Identité des utilisateurs anonymes

Vous constatez que par défaut l’identité des utilisateurs anonyme est le groupe IUSR. Remarquez qu’il est possible d’utiliser le compte d’identité du pool d’applications (actuellement NetworkService) pour représenter l’identité des utilisateurs anonymes.

Maintenant on peut se connecter sur notre application en utilisant l’adresse http://localhost.

L'identité du processus en cours d'exécution est "Service Réseau"

L'identité du processus en cours d'exécution est "Service Réseau"

Vous constatez que l’identité du processus est Service Réseau et celui de l’utilisateur est un utilisateur anonyme Windows. Bien évidemment, lorsque nous accédons à la page consacré aux visiteurs, notre application ne peut se connecter à notre serveur SQL.

L'identité "Service réseau" ne peut se connecter à la base de données.

L'identité "Service réseau" ne peut se connecter à la base de données.

Pour régler ce problème, il suffirait d’ajouter le compte Service Réseau en tant qu’utilisateur de notre serveur SQL Server. Comme je l’ai expliqué dans la troisième partie de cet article, c’est une très mauvaise idée. Nous allons donc créer un compte de service dédié à notre application.

Création et paramétrage du compte de service

Pour créer un compte de service, rien de plus simple que d’ajouter un utilisateur. Dans le gestionnaire de l’ordinateur, dans le noeud Utilisateurs et groupes locaux, nous sélectionnons le noeud Utilisateurs et faisons un clic droit afin de choisir l’option Nouvel Utilisateur….

Création d'un compte de service pour l'application

Création d'un compte de service pour l'application

Lorsque l’on crée un compte utilisateur en vu d’être utilisé par une application de type « service », il faut s’assurer que la case à cocher le mot de passe n’expire jamais soit cochée.

Maintenant que le compte de service est utilisé, il suffit de changer le compte de service de notre pool IIS CatTond. Pour ce faire, dans la liste des pools IIS nous sélectionnons le pool IIS CatTond, un clic droit afin de sélectionner l’option Paramètres avancées. Dans la section Modèle de processus, dans le paramètre Identité, nous cliquons sur le bouton « … » afin de changer l’identité de notre pool IIS.

Changement de l'identité du pool IIS

Changement de l'identité du pool IIS

Une nouvelle fenêtre apparait vous proposant de choisir un compte intégré ou un compte personnalisé. Choisissez l’option Compte personnalisé et cliquez sur Définir.

Définition de l'identité du pool IIS avec un compte personnalisé

Définition de l'identité du pool IIS avec un compte personnalisé

Une nouvelle fenêtre apparait de nouveau vous proposant de saisir le compte utilisateur et le mot de passe à utiliser pour le pool IIS.

Définition du nom et du mot de passe de l'identité du pool IIS

Définition du nom et du mot de passe de l'identité du pool IIS

Maintenant, si on accède de nouveau à l’application, on remarque que le compte utilisateur Windows du processus IIS a changé. Bien évidemment, il n’est toujours pas possible d’accéder à SQL Server…

L'identité du processus en cours d'exécution est celui du compte "CatTond.Service"

L'identité du processus en cours d'exécution est celui du compte "CatTond.Service"

Ajout du compte de service dans SQL Server.

Pour que notre application (le compte de service CatTond.Service) puisse se connecter à notre SQL Server, il faut ajouter ce dernier et lui octroyer des droits de lecture/écriture sur la base de données. Pour cela nous allons dans SQL Management Studio, nous nous connectons à notre base de données et dans le noeud Securité/Connexions, nous faisons un clic droit et choisissons Nouvelle connexion.

Ajout de l'identité du pool IIS dans les utilisateurs de SQL Server

Ajout de l'identité du pool IIS dans les utilisateurs de SQL Server

Ici nous remplissons notre compte de service, on lui attribut comme base de données par défaut celle de notre application. Maintenant passons à la page Mappage de l’utilisateur afin d’attribuer les droits de lecture/écriture sur la base de données.

Définition des rôles de l'utilisateur CatTond.Service dans SQL Server

Définition des rôles de l'utilisateur CatTond.Service dans SQL Server

Maintenant les visiteurs ont accès au catalogue.

Affichage du catalogue des produits

Affichage du catalogue des produits

Simulation d’une faille dans l’accès des visiteurs

L’un des défauts de cette configuration est le fait que les visiteurs de notre application, ont la possibilité (indirectement) d’accéder à la base de données en écriture. Dans la page Visiteurs.aspx, j’ai volontairement ajouté un bouton qui exécute une requête SQL de type UPDATE dans le contexte courant du visiteur afin de modifier le prix de manière aléatoire de la première tondeuse.

Modification du catalogue des produits sans authentification d'un utilisateur autorisé

Modification du catalogue des produits sans authentification d'un utilisateur autorisé

Cette simulation vous montre qu’un visiteur (c’est à dire un utilisateur quelconque), peux « facilement » modifier votre catalogue si ce dernier trouve une faille dans la page ASP .NET !

Mise en place de l’authentification Windows pour l’accès administrateur (sous ASP .NET).

Précédemment, nous utilisons l’authentification anonyme, c’est à dire n’importe quel utilisateur peut se connecter à notre application et en particulier la page dédié aux administrateurs. Nous allons donc mettre en place l’authentification Windows, pour cela, dans les autorisations d’IIS de notre site, nous activons l’authentification Windows.

Activation de l'authentification Windows

Activation de l'authentification Windows

Si l’on revient sur notre site on se rend compte que l’authentification Windows ne fonctionne pas !

L'identité du processus en cours d'exécution est celui du compte "CatTond.Service"

L'identité du processus en cours d'exécution est celui du compte "CatTond.Service"

En effet, l’authentification anonyme est activée, donc nous pouvons toujours nous authentifier de façon anonyme !

Rendre la page « Administrateurs.aspx » visible uniquement via l’authentification Windows

Maintenant nous allons rendre la page Administrateurs.aspx visible uniquement aux utilisateurs authentifiés. Pour cela nous devons modifier le fichier web.config de notre application :

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.web>
        <authentication mode="Windows" />
    </system.web>
    <!-- Protéger la page "Administrateurs.aspx" -->
    <location path="Administrateurs.aspx">
        <system.web>
            <authorization>
                <deny users="?"/>
            </authorization>
        </system.web>
    </location>
</configuration>

Dans ce fichier web.config, nous avons spécifié que les utilisateurs anonymes n’ont pas accès au fichier Administrateurs.aspx. Pour pouvoir accéder à cette page, nous devons alors utiliser un autre moyen d’authentification, qui est bien évidemment l’authentification Windows.

REMARQUE : Le fait de spécifier les droits d’accès aux pages dans le web.config, indique que l’accès est géré par ASP .NET !

Si nous nous connectons sur la page Administrateurs.aspx, nous devons fournir un login et mot de passe Windows valide présente sur l’environnement où se trouve IIS.

Authentification Windows de l'administrateur du catalogue

Authentification Windows de l'administrateur du catalogue

Une fois connecté, voici la page qui s’affiche :

Informations sur l'utilisateur en cours lors de l'authentification de l'administrateur du catalogue

Informations sur l'utilisateur en cours lors de l'authentification de l'administrateur du catalogue

Comme vous pouvez le constater, après authentification l’identité utilisateur récupérée est celle du login saisie précédemment.

Par contre si après plusieurs tentative, le login et/ou mot de passe est incorrect, IIS retourne un message d’insulte d’une erreur 401 :

Erreur 401 produite par IIS 7.0 en cas d'échec d'authentification

Erreur 401 produite par IIS 7.0 en cas d'échec d'authentification

Renforcer la sécurité via l’emprunt d’identité

Maintenant que nous avons la possibilité de séparer les accès à notre application entre les visiteurs et les administrateurs, il nous reste à corriger un défaut : Les visiteurs peuvent toujours exécuter des requêtes de modification (UPDATE) au niveau de la base de données.

Nous allons donc activer l’emprunt d’identité ASP .NET, pour cela dans les autorisations d’IIS de notre site, activez « Emprunt d’identité ASP .NET« .

Activation de l'emprunt d'identité

Activation de l'emprunt d'identité

Toujours dans Emprunt d’identité ASP .NET, faisons un clic droit et choisissons Modifier…. Une nouvelle fenêtre apparait :

Définittion de l'identité à emprunter

Définittion de l'identité à emprunter

Vous constatez que vous pouvez emprunter l’identité de l’utilisateur authentifié, ou celle d’un autre utilisateur. Dans le dernier cas, je trouve cette option de très peu d’utilité car il suffit le plus souvent de désactiver l’emprunt d’identité et de choisir comme compte de service du pool associé, le compte utilisateur désiré. Nous laissons dans notre cas l’option Utilisateur authentifié.

Comme expliqué dans la troisième partie concernant la remarque de IIS 7.0, vous devez ajouter ce fragment XML dans le web.config de l’application :

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
</system.webServer>

Si nous revenons à notre application :

Vérification de l'identité emprunté pour l'authentification anonyme

Vérification de l'identité emprunté pour l'authentification anonyme

Vous pouvez constater que l’identité du processus est devenu le compte IIS des utilisateurs anonymes. Accédons maintenant à la page Visiteurs.aspx :

Message d'erreur indiquant que les utilisateurs anonymes de peuvent se connecter à SQL Server

Message d'erreur indiquant que les utilisateurs anonymes de peuvent se connecter à SQL Server

Le message indique que l’utilisateur IUSR, n’a pas accès à la base de données CatTondBD. Du côté de la page Administrateurs.aspx on obtient la même chose mais cette fois ci avec le compte utilisateur administrateur de l’application Gilles.Tourreau.

Message d'erreur indiquant que l'utilisateur Gilles.Tourreau ne peut se connecter à SQL Server

Message d'erreur indiquant que l'utilisateur Gilles.Tourreau ne peut se connecter à SQL Server

Changement du compte des utilisateurs anonymes

Au niveau de SQL Server, vous l’aurez compris, il est nécessaire de donner des droits de lecture au compte des utilisateurs anonyme IUSR. Or, cela rejoins le même problème évoqué concernant les comptes de service : Ce compte risque d’être partagée par diverses applications ASP .NET. Si on donne un privilège pour ce compte (en l’occurrence le droit d’accès à notre base de données), on risque donc de donner ce privilège à d’autres applications qui n’en ont pas besoin !

Pour pallier à ce problème, il suffit de créer un compte utilisateur CatTond.Anonyme (avec un mot de passe fort et qui n’expire jamais). Une fois que le compte est crée, il faut spécifier à IIS que nous utiliserons ce compte pour les utilisateurs anonymes de notre application. Dans les paramétrages d’authentification d’IIS, il suffit de modifier les propriétés de l’authentification anonyme :

Modification des options de l'authentification anonyme

Modification des options de l'authentification anonyme

Ensuite, on défini le compte utilisateur crée précédemment comme représentant l’identité des utilisateurs anonymes :

Définition de l'identité des utilisateurs anonymes

Définition de l'identité des utilisateurs anonymes

Si maintenant nous nous connectons à la page consacrée aux visiteurs de notre application, bien évidement l’accès à SQL Server échoue, mais l’identité utilisée pour se connecter à SQL Server est celui de notre compte anonyme.

Le compte utilisateur des utilisateurs anonymes ne peut se connecter à SQL Server

Le compte utilisateur des utilisateurs anonymes ne peut se connecter à SQL Server

Modification des droits au niveau de SQL Server.

Le compte de service « CatTond.Service » n’est plus utilisé pour authentifier nos utilisateurs sur la base de données. Nous devons donc effectuer les modifications suivantes au niveau de SQL Server :

  • Suppression de la connexion « CatTond.Service » de SQL Server (n’est plus utilisé).
  • Ajout du compte « CatTond.Anonyme » dans SQL Server avec comme rôle : « db_datareader » uniquement sur la base de données « CatTondBD ».
  • Ajout du compte « Gilles.Tourreau » dans SQL Server avec comme rôle : « db_datareader » et « db_datawriter » uniquement sur la base de données « CatTondBD ».

Une fois ces modifications réalisées, notre application est maintenant bien sécurisée. Grâce à l’emprunt d’identité utilisateur, nous accédons aux ressources de notre application via l’identité réelle de nos utilisateurs.

Utiliser l’identité du pool d’applications comme identité des utilisateurs anonyme.

Précédemment, nous avons crée et utilisé un compte spécifique pour les utilisateurs anonymes. Si on héberge une trentaine d’application sur notre serveur, cela risque de faire beaucoup de compte à gérer. On peut bien évidemment utiliser des groupes pour faciliter leurs manipulation, mais il existe un autre moyen (ou plutôt une politique de sécurité) qui consiste à dire :

  • Par défaut, l’identité utilisée par tous les utilisateurs qui utilise notre application est celui du pool d’applications.
  • Les pages disposant d’une autorisation spéciale, utiliseront l’identité de l’utilisateur authentifié.

Pour mettre en oeuvre cette politique, il suffit de régler dans notre application que l’identité des utilisateurs anonyme n’utilise pas un compte utilisateur spécifique mais directement l’identité du pool d’application.

Définition de l'identité des utilisateurs anonymes comme identité du pool IIS associé

Définition de l'identité des utilisateurs anonymes comme identité du pool IIS associé

Dans ce cas, nous devons réaliser les modifications suivantes sur notre serveur IIS :

  • Suppression de la connexion CatTond.Anonyme de SQL Server (n’est plus utilisé).
  • Ajout du compte CatTond.Service dans SQL Server avec comme rôle : db_datareader uniquement sur la base de données CatTondBD.

Renforcer encore plus la sécurité sur les fichiers de l’application ASP .NET.

Par mesure de précaution, il est recommandé de donner les droits les plus bas au niveau des fichiers de votre application ASP .NET. Si nous regardons par exemple, les droits associés par défaut aux fichiers de notre application :

Droits utilisateurs par défaut sur les fichiers du site Web

Droits utilisateurs par défaut sur les fichiers du site Web

Vous constatez que par exemple les utilisateurs du serveur ont des droits de lecture sur nos fichiers de notre application ASP .NET. Ainsi, un utilisateur disposant des droits pour se connecter au serveur (via Terminal Services par exemple) peut regarder le contenu de ces fichiers !

Pour définir les droits les plus basiques sur les fichiers de notre application, il suffit de donner les droits suivants :

  • Contrôle total : pour les administrateurs (il faut bien que quelqu’un ait les droits absolus sur la mise en production de notre application).
  • Lecture : pour le compte de service de notre pool IIS de notre application.
Définition des droits utilisateurs sur les fichiers du site Web

Définition des droits utilisateurs sur les fichiers du site Web

Votre application continue de fonctionner avec les droits les plus bas au niveau de l’accès aux fichiers Windows.

Définition des droits pour l’administrateur de l’application

Lorsque vous accédez à la page Administrateurs.aspx de notre application, vous constatez que malgré après avoir saisi 3 fois le mot de passe, vous ne disposez pas des droits d’accès à cette page.

Le compte "Gilles.Tourreau" ne peut accéder aux fichiers du site web

Le compte "Gilles.Tourreau" ne peut accéder aux fichiers du site web

Bien évidemment, il faut donner des droits de Lecture pour notre administrateur Gilles.Tourreau sur la page Administrateurs.aspx

Définition des droits sur les fichiers pour l'utilisateur "Gilles.Tourreau"

Définition des droits sur les fichiers pour l'utilisateur "Gilles.Tourreau"

Conclusion

Ainsi se termine ce long article, qui j’espère vous permettra de mieux comprendre les concepts de sécurité et d’authentification dans les applications ASP .NET se basant sous IIS.

Une chose importante à retenir : Toujours limiter au maximum les privilèges des comptes utilisateurs et surtout prenez garde au partage de compte utilisateur qui soient intégrés ou non à Windows.

Connaissances en matière de sécurité sur les produits Microsoft.

J’aimerais ajouter une petite remarque concernant les connaissances de base en matière de sécurité de certaines personnes (Le plus souvent des développeurs et administrateurs systèmes !).

Je suis impressionné de constater, que beaucoup de ces personnes (disposant le plus souvent de responsabilités importantes au sein de leur entreprise) n’ont aucunes notions où se fiche complètement des problèmes de sécurité concernant leurs applications sous pretexte que :

  • « La sécurité est sans importance pour nous tant que cela fonctionne » : Ben voyons, il suffit qu’un jour qu’un petit malin efface tout le contenu de votre base de données…
  • « Comme mon application ne fonctionnait pas sous d’autres comptes utilisateurs, j’ai réussi à la faire fonctionner sous le compte administrateur du domaine » : Parfait, la porte est grande ouverte pour accéder au système complet de votre entreprise !
  • « Les concepts de sécurité sont trop complexes à comprendre » : Dans ce cas, il suffit de changer de métier ! Par exemple, devenir administrateur du rayon des slips d’une grande surface.
  • et j’en passe …

Tout çà pour dire que depuis 10 ans, Microsoft s’efforce à mettre à disposition des utilisateurs des ressources importantes (Documentations, articles, livres,…etc), concernant la sécurité axé bien évidemment sur leurs produits. Les sites phares à consulter régulièrement sont :

Faites attention lorsque vous effectuez une recherche sur internet concernant un problème de sécurité. Sous les forums, beaucoup « d’informaticien du Dimanche » répondent aux questions !

Privilégiez toujours la documentation officielle du concepteur du produit !

Fichier joint : Application Web Exemple

15 réflexions au sujet de « [ASP .NET/IIS] Comprendre le concept d’identité, privilège et d’authentification utilisateur sous IIS et ASP .NET »

  1. Bonjour.
    C’est franchement exactement ce que je recherchais.
    Cet article est touit simplement facile de compréhension et accessible je le pense à tout le monde.
    Bravo et merci.
    Rares sont les sites en français ayant l’allure de cet aricle.

  2. Un grand merci pour cet article de grande qualité et qui apporte énormément de réponses

  3. Je rejoins l’avis de Txang64. Excellent article accessible à tous. Je vais garder cette article sous la mains pour le recommander à tous les développeurs avec qui j’aurai l’occasion de travailler sur des site web avec IIS.

  4. Bonjour,

    Je suis justement sur cette idée de mise en oeuvre cette sécurité.

    Seule faille que j’ai pu identifier puisque je suis avant tout architecte en bases de données et mon objectif est de chaîner l’authentification Windows de bout en bout dès l’entrée de l’application, jusqu’à l’accès BDD SQL SERVER :

    Si j’applique à la lettre la politique de sécurité que vous cité :
    « – Par défaut, l’identité utilisée par tous les utilisateurs qui utilise notre application est celui du pool d’applications.
    – Les pages disposant d’une autorisation spéciale, utiliseront l’identité de l’utilisateur authentifié. »

    Comment je contre, les utilisateurs avec pouvoir qui sont authentifiés à SQL SERVER en leur nom (compte de groupe déclaré dans SQL SERVER) pour qu’il n’y accèdent pas avec une connexion ODBC basique simple à mettre en oeuvre avec Access et fassent toutes les manipulations de données sans contrôle ?

    D’avance merci. Puisque même sans connaissance du développement, j’ai tout compris.

    Cordialement,
    Etienne

  5. Bonjour,

    L’inconvénient d’utiliser l’authentification Windows en utilisant les comptes propres aux utilisateurs et qu’il peuvent accéder directement à la base de données (sans passer par vos applications). Il n’y a (à ma connaissance) aucune possibilité de limiter cet accès au niveau SQL Server.
    J’avais oublié de mentionner cette problématique dans mon article. J’essayerai de faire un petit post dessus.

    Cordialement

  6. Bonjour

    Merci encore pour cet article que je considère comme une référence de base pour les admins NT. j’aimerai savoir si possible que l’auteur puisse nous donner des références bibliographiques (Lives, papres, webcasts,) qui traitent de facon trés détaillée ce sujet … de préférence ca soit en anglais

    Merci

  7. Ping : Informatique by hprdcore - Pearltrees

  8. Bonjour M. Tourreau au milieu de votre article vous dite: Nous allons utilisez 3 pages ASP .NET simples (téléchargeable à la fin de l’article) .

    Je ne trouve pas les liens et j’aurais aimé continué à suivre votre article en essayant pour me permettre de mieux comprendre.
    Merci

  9. Ping : silat | Pearltrees

  10. Un grand merci pour cet article extrêmement riche et très clair qui m’a permis de publier mon tout petit site Web en Intranet qui ne parvenait pas à écrire dans une base Access placée sur un des serveurs.

  11. Cet article est vraiment un trésor pour moi, c’est le puzzle qui m’a manqué !!! pour une base correcte sur ce sujet.

    MERCI Monsieur

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.