Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

IIS7 : Configuration des handlers pour l'upload de fichier - interdire certains fichiers de s'exécuter | accéder à des fichiers .cs, .aspx

Comment configurer IIS7 pour que les fichiers uploadés par les utilisateurs soient facilement redistribuables et en toute sécurité ?

L'upload de fichier dans un site web est un sujet sensible d'un point de vue sécurité, de nombreuses questions sont souvent négligées : Quels noms donnés aux fichiers uploadés ? A t'on besoin d'autoriser tous les types de fichiers ? Dans quel répertoire stocker les fichiers ? etc ... N'oubliez pas que vous laisser la possibilité à un pirate potentiel d'envoyer un fichier sur votre serveur !

Si bien que dans certains cas, il peut arriver que des fichiers .aspx, .config puissent être uploadés sur le serveur. Nous allons voir dans ce post comment configurer IIS7 pour que ce genre de fichier ne pose pas de problèmes.

Les explications ci-dessous sont pour un site web IIS7 hebergé dans un pool d'application avec le "Managed pipeline mode" "Integrated" et non "Classic" le mode de compatibilité pour IIS6. Nous partons du principe que nous écrivons les fichiers directement sur le disque et non dans une base de données et que tous les fichiers doivent être stocké y compris les fichiers .cs, .config.
A part si vous avez une très bonne raison je vous déconseille fortement de stocker ce genre de fichiers avec les extensions d'origines.

delete Ne pas stocker de fichier .cs ou .config sauf si vous avez de très bonne raison
delete Ne pas conserver les noms de fichiers d'origine

Tout d'abord, il faut créer un nouveau dossier réservé aux uploads, vous pouvez créer un dossier dans le même dossier que le site web, mais pour être plus tranquille, je vous conseille vivement de créer un dossier virtuel. Cela permet d'une part de mettre les uploads sur un autre disque, d'avoir tous les fichiers "applicatifs" dans un même dossier et enfin cela permet de limiter les risques.

accept Créer un dossier Virtuel réservé à l'upload

L'avantage de IIS7, c'est que toute la configuration d'un site web est faite via le fichier web.config. Pour interdire l'exécution des pages aspx pour un dossier précis, nous avons 2 solutions : soit on supprime les handlers dispensables soit on supprime tous les handlers puis on rajoute le handler voulu. Je vous conseille fortement la deuxième solution pour plus de sécurité !

accept Supprimer tous les handlers du dossier upload puis on rajoute le StaticFile Handler

Pour supprimer un handler dans "Internet Information Services (IIS) Manager", positionnez vous sur le dossier choisi, puis choisissez la feature "Handler Mappings", vous pouvez ainsi supprimer les handlers souhaités.

image image

Cette manipulation va créer un fichier de config qui se situe dans le dossier choisi, voila ce que contient ce fichier :

<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <handlers> <remove name="PageHandlerFactory-Integrated" /> </handlers> </system.webServer> </configuration>

Pour supprimer tous les handlers d'un coup, je n'ai pas vu d'options dans la console de gestion de IIS, il faut modifier directement le fichier de config. Pour cela utilisez la balise <clear /> puis rajoutez le handler souhaité via la balise <add />

<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <handlers> <clear /> <add name="StaticFile" path="*" verb="*" modules="StaticFileModule" resourceType="Either" requireAccess="Read" verb="GET" /> </handlers> </system.webServer> </configuration>

A noter que puisque ce dossier ne servira qu'à la lecture de fichier on peut restreindre le verbe HTTP à GET.

Pour voir les différents paramètres possibles pour l'ajout d'un handler, consultez cet article IIS 7.0: add Element for handlers (IIS Settings Schema) 

Si votre dossier ne contient que des images JPG alors vous pouvez (devez) mettre "*.jpg" dans l'attribut path.

accept Restreindre le StaticFile handler qu'au verbe GET
delete Ne pas utiliser * en path si vous avez seulement 2 ou 3 extensions connues à délivrer

Si vous êtes curieux de voir comment est configuré le StaticFileModule il s'agit d'un module natif configuré ainsi dans le applicationHost.config :

<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <globalModules> <add name="StaticFileModule" image="%windir%\System32\inetsrv\static.dll" /> </globalModules> </system.webServer> </configuration>

Avec cette configuration, quid de l'accès du fichier web.config ? En effet puisque l'on a supprimé tous les handlers, notre configuration laisse penser que les fichiers de config sont publiquement accessibles. Heureusement par défaut IIS est configuré avec le module "RequestFiltering". En accédant à votre fichier de .config vous aurez ce message d'erreur :

HTTP Error 404.7 - Not Found
The request filtering module is configured to deny the file extension.

Le module RequestFiltering est configuré au niveau du fichier applicationHost.config ce fichier est situé dans le dossier "C:\Windows\System32\inetsrv\config", il s'agit du fichier de configuration global de IIS.

Petite astuce, si vous utilisez un OS 64bits, alors toutes les applications 32 bits vont voir leurs accès au dossier "C:\Windows\System32\" redirigé vers le dossier "C:\Windows\SysWOW64" c'est pour ça que Visual Studio ou tout autre éditeur 32 bits ne trouvera pas le fichier ou alors un fichier vide. Il faut donc utiliser une application 64bits comme notepad afin d'éditer ce fichier.

Par défaut, voici la configuration du requestFiltering par défaut

<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <security> <requestFiltering> <fileExtensions allowUnlisted="true" applyToWebDAV="true"> <add fileExtension=".asax" allowed="false" /> <add fileExtension=".ascx" allowed="false" /> <add fileExtension=".master" allowed="false" /> <add fileExtension=".skin" allowed="false" /> <add fileExtension=".browser" allowed="false" /> <add fileExtension=".sitemap" allowed="false" /> <add fileExtension=".config" allowed="false" /> <add fileExtension=".cs" allowed="false" /> <add fileExtension=".csproj" allowed="false" /> <add fileExtension=".vb" allowed="false" /> <add fileExtension=".vbproj" allowed="false" /> <add fileExtension=".webinfo" allowed="false" /> <add fileExtension=".licx" allowed="false" /> <add fileExtension=".resx" allowed="false" /> <add fileExtension=".resources" allowed="false" /> <add fileExtension=".mdb" allowed="false" /> <add fileExtension=".vjsproj" allowed="false" /> <add fileExtension=".java" allowed="false" /> <add fileExtension=".jsl" allowed="false" /> <add fileExtension=".ldb" allowed="false" /> <add fileExtension=".dsdgm" allowed="false" /> <add fileExtension=".ssdgm" allowed="false" /> <add fileExtension=".lsad" allowed="false" /> <add fileExtension=".ssmap" allowed="false" /> <add fileExtension=".cd" allowed="false" /> <add fileExtension=".dsprototype" allowed="false" /> <add fileExtension=".lsaprototype" allowed="false" /> <add fileExtension=".sdm" allowed="false" /> <add fileExtension=".sdmDocument" allowed="false" /> <add fileExtension=".mdf" allowed="false" /> <add fileExtension=".ldf" allowed="false" /> <add fileExtension=".ad" allowed="false" /> <add fileExtension=".dd" allowed="false" /> <add fileExtension=".ldd" allowed="false" /> <add fileExtension=".sd" allowed="false" /> <add fileExtension=".adprototype" allowed="false" /> <add fileExtension=".lddprototype" allowed="false" /> <add fileExtension=".exclude" allowed="false" /> <add fileExtension=".refresh" allowed="false" /> <add fileExtension=".compiled" allowed="false" /> <add fileExtension=".msgx" allowed="false" /> <add fileExtension=".vsdisco" allowed="false" /> </fileExtensions> <verbs allowUnlisted="true" applyToWebDAV="true" /> <hiddenSegments applyToWebDAV="true"> <add segment="web.config" /> <add segment="bin" /> <add segment="App_code" /> <add segment="App_GlobalResources" /> <add segment="App_LocalResources" /> <add segment="App_WebReferences" /> <add segment="App_Data" /> <add segment="App_Browsers" /> </hiddenSegments> </requestFiltering> </security> </system.webServer> </configuration>

Si vous voulez que les fichiers .cs & co soient accessible, il faut modifier le fichier de config de votre dossier manuellement, je n'ai rien vu permettant de configurer le requestFiltering via la console IIS. Surtout ne modifier pas votre fichier ApplicationHost.config ce fichier est utilisé pour tous les sites web de votre serveur !

Voici le fichier de config nous permettant d'avoir accès au fichier C# (.cs)

<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <security> <requestFiltering> <fileExtensions> <remove fileExtension=".cs" /> <add fileExtension=".cs" allowed="true" /> </fileExtensions> </requestFiltering> </security> </system.webServer> </configuration>

Pour en savoir plus sur ce module très complet, je vous invite à consulter cet page : IIS 7.0: requestFiltering Element for security (IIS Settings Schema)

accept Configurer le requestFiltering pour les fichiers "dangereux"

Malheureusement, si vous accédez à votre fichier .cs via IIS, vous aurez alors un autre message d'erreur :

HTTP Error 404.3 - Not Found
The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.

Ce message d'erreur est renvoyé par le StaticFileModule, en effet notre requête est bien redirigé vers ce module, mais celui-ci ne connait pas le type mime avec lequel renvoyé le fichier, il faut alors spécifier le type MIME des fichiers ".cs"

<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <staticContent> <mimeMap fileExtension=".cs" mimeType="text/plain" /> </staticContent> </system.webServer> </configuration>

accept Configurer les types mimes pour les extensions de fichier non connus nativement par IIS.

Le fichier web.config de notre dossier Upload ressemble alors à :

<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <handlers> <clear /> <add name="StaticFile" path="*" verb="*" modules="StaticFileModule" resourceType="Either" requireAccess="Read" verb="GET" /> </handlers> <security> <requestFiltering> <fileExtensions> <remove fileExtension=".cs" /> <add fileExtension=".cs" allowed="true" /> </fileExtensions> </requestFiltering> </security> <staticContent> <mimeMap fileExtension=".cs" mimeType="text/plain" /> </staticContent> </system.webServer> </configuration>

D'un point de vue sécurité est-ce suffisant ?

Je vous conseille de ne pas laisser votre fichier de config dans le même dossier que votre dossier d'upload, ainsi vous serez certain que votre application n'écrasera pas votre fichier de config.
Vous pouvez alors stocker le contenu du fichier de config, dans le fichier de config du parent grâce à la balise <location path="upload"> n'oubliez pas de mettre allowOverride à false afin qu'un fichier de config stocké dans le dossier upload ou un de ses sous-dossier n'écrasent pas votre configuration.

<?xml version="1.0" encoding="UTF-8"?> <!-- fichier web.config de la racine du site web --> <configuration> <location path="upload" allowOverride="false"> <!-- contenu du fichier de config upload --> </location> </configuration>

delete Ne pas stocker votre fichier de configuration dans le dossier d'upload

Si vous avez besoin d'autres options de sécurité et de possibilité de configuration, je vous conseille de créer votre propre module HTTP. En créant votre propre module vous aurez alors plus de facilité pour exécuter des règles métiers : autorisation par fichier, statistique, etc ... De plus faire un nouveau module permettra d'utiliser le StaticFile handler.

Le top de la sécurité serait de refaire un handler StaticFile qui par exemple renverra le fichier web.config.upload lorsque l'utilisateur demande le fichier web.config. Il faudra préalablement ajouter l'extension .upload lorsque vous enregistrez le fichier. Votre handler personnalisé devra bien sur utiliser les mime types configuré dans le fichier de config, la création d'un handler personnalisé n'empêche pas la création d'un module dédié aux statistique, c'est même préférable que de gérer les statistiques dans votre handler.

Quels droits donné sur le dossier d'upload ?

Lorsqu'un utilisateur envoie un fichier vers votre site web, c'est ASP.net qui va écrire ce fichier sur le disque. Pour cela il utilise le compte "NETWORK SERVICE", il faut donc lui donner les droits d'écriture sur ce dossier. Si vous avez malgré tout des problèmes de droits lors de l'upload, utilisez Process Monitor pour comprendre pourquoi.

accept Donner le droit d'écriture au compte "Network Service"

Avez-vous d'autres astuces à partager sur ce sujet ? D'autres conseils que j'ai oubliés ?

Posted: mardi 14 octobre 2008 19:49 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

Pas de commentaires

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Changer l’adresse d’une ferme Office Web Apps associée à SharePoint par Blog de Jérémy Jeanson le il y a 5 heures et 20 minutes

- Une ferme #SharePoint 2013 dans @Azure en quelques clics (1ère partie) ! par Le blog de Patrick [MVP SharePoint] le 08-28-2014, 18:52

- SharePoint 2013: Préparation de la migration - Création des site Templates dans 2010 et 2013 par Blog Technique de Romelard Fabrice le 08-20-2014, 16:31

- [ #Yammer ] How to change interface language ? Comment changer la langue de l’interface ? par Le blog de Patrick [MVP SharePoint] le 08-20-2014, 14:21

- Onedrive Sync Engine Host : CPU à 100% par Le petit blog de Pierre / Pierre's little blog le 08-06-2014, 22:22

- SharePoint : Bug sur la gestion des permissions et la synchronisation Office par Blog Technique de Romelard Fabrice le 07-10-2014, 11:35

- SharePoint 2007 : La gestion des permissions pour les Workflows par Blog Technique de Romelard Fabrice le 07-08-2014, 11:27

- TypeMock: mock everything! par Fathi Bellahcene le 07-07-2014, 17:06

- Coding is like Read par Aurélien GALTIER le 07-01-2014, 15:30

- Mes vidéos autour des nouveautés VS 2013 par Fathi Bellahcene le 06-30-2014, 20:52