ASPNL logo (1 kb)
zaterdag 17 mei 2008




Microsoft MVP

.NET Codewise Community
<< vorige | overzicht | volgende >>

ASP.NET Applicaties Beveiligen met Windows Beveiliging

Door Michiel van Otegem
22 juni 2006

Het beveiligen van een web applicatie is minder eenvoudig dan het beveiligen van een Windows applicaties. Omdat web applicaties wel veel meer risico lopen om misbruikt te worden, is het echter veel belangrijker om web applicaties goed te beveiligen. Hiervoor is goede kennis van de beveilingsaspecten van ASP.NET onmisbaar.

ASP.NET applicaties kunnen op verschillende manieren beveiligd worden, via Windows beveiliging, met HTML formulieren, en met Microsoft Passport. De standaard methode is Windows beveiliging, dat gebruik maakt van de beveiliging die ook gebruikt wordt voor bestanden en applicaties in reguliere Windows applicaties. Een web applicatie beveiligen is echter een stuk ingewikkelder dan het beveiligen van een Windows applicatie. Sommige van de aspecten die komen kijken bij beveiliging met Windows beveiliging zijn ook van toepassing op de andere vormen van beveiliging, dus bespreek ik Windows beveiliging eerst. In een volgend artikel bespreek ik andere vormen van beveiliging.
In een Windows applicatie is beveiliging betrekkelijk simpel. Als je eenmaal ingelogd bent op een Windows PC, gebruiken applicaties jouw identiteit om bestanden te openen of resources te gebruiken. Als je rechten niet voldoende zijn om een bestand te openen of een resource te gebruiken, dan werkt de applicatie niet. De enige uitzondering vindt plaats als COM componenten die een applicatie gebruikt onder Windows Component Services (WCS) werken. Een component in WCS kan uitgevoerd worden met een andere identiteit dan die van de huidige gebruiker, er van uitgaande dat deze gebruiker voldoende rechten hebt om het component te mogen starten in WCS. De beveiliging van ASP.NET applicaties heeft veel weg van het werken met WCS, dus als je daar al ervaring mee hebt, zul je ASP.NET beveiliging makkelijker begrijpen. Het belangrijkste punt is dat er twee verschillende dingen zijn als het gaat om de beveiliging: de toegang tot de pagina (mag een pagina uitgevoerd worden) en onder welke identiteit (Windows account) de pagina wordt uitgevoerd (en tot welke resources de pagina toegang heeft).
Als je inlogt op een Windows PC, wordt je identiteit op dat moment vastgesteld. Vervolgens wordt op basis van rechten (autorisatie) vastgesteld wat je wel en niet mag. Wanneer je werkt met ASP.NET applicaties, wordt het identificeren en autoriseren van gebruikers gedaan in combinatie met Internet Information Server (IIS). Wanneer een ASP.NET pagina opgevraagd wordt, komt deze aanvraag binnen bij IIS. IIS zal zonodig een gedeelte van de identificatie op zich nemen. De samenwerking tussen ASP.NET en IIS, alsmede de onderliggende gevolgen voor hoe toegang verkregen wordt tot resources maakt beveiliging ingewikkeld. Het is daarom verstandig om te beginnen bij hoe IIS aanvragen afhandelt van gewone HTML bestanden, plaatjes en ASP bestanden, alvorens te kijken wat voor invloed dit heeft op ASP.NET.

Beveiliging van Internet Information Server

Omdat je niet wil dat een gebruiker willekeurig toegang heeft tot bestanden op de web server bevat IIS verschillende mechanismen om de toegang te beperken. Allereerst zijn alleen bestanden toegankelijk die in mappen staan die gemarkeerd zijn als virtuele directory. Alle bestanden die daarbuiten staan, zijn niet (direct) toegankelijk, omdat er geen URL is die correspondeert met bestanden die buiten de virtuele directories staan. Verder kan IIS ook ingesteld worden zodat alleen bepaalde domeinnamen of IP-adressen toegang kunnen verkrijgen tot de virtuele directories. Overigens is dat systeem niet geheel onfeilbaar, omdat ervaren hackers domeinnamen en IP-adressen kunnen simuleren. Als laatste kun je gebruik maken van de mogelijkheden die Windows NT/2000/XP biedt om bestanden op een NTFS file systeem te beveiligen. Aan de hand van Access Control Lists (ACLs) kun je bepalen wie toegang heeft tot een bestand of map en wie niet. Daarvoor moet je eerst bepalen wie iemand eigenlijk is. Dit kan op vier verschillende manieren:
  • Basic Authentication
  • Digest Authentication
  • Integrated Windows Authentication
  • SSL Certificate Authentication
Welke methode het best geschikt is, is afhankelijk van of een gebruiker via het lokale netwerk een server benadert of via het internet. In alle gevallen is de identiteit die vastgesteld wordt die van een Windows NT account dat gedefinieerd is op de web server of in het domein waar de web server onderdeel van is.
Via het internet zijn Basic Authentication en Digest Authetication de twee belangrijkste methodes van identificatie. Wanneer je een bestand opvraagt dat beveiligd is via een van deze methodes, krijg je een popup-venster te zien dat vraagt om je gebruikersnaam en wachtwoord. Dit werkt goed, omdat de identificatie gaat via het HTTP protocol, en dus in principe met elke browser werkt die een van beide methodes ondersteunt (zie voor meer informatie "Basic Authentication en Digest Authentication").

Basic Authentication en Digest Authentication
Basic Authentication en Digest Authentication werken op basis van standaard HTTP mechanismen. Wanneer een pagina beveiligd is, stuurt de web server een statuscode 401 Access Denied terug met de mogelijke manieren waarop iemand zich zelf kan identificeren. Het is aan de browser om te bepalen welke methode gebruikt wordt. Over het algemeen zal de browser de veiligste methode kiezen die het gebruiken kan. In het geval van Basic Authentication krijg je een popup-venster te zien, waarin je je gebruikersnaam en wachtwoord moet invullen. De gebruikersnaam en het wachtwoord worden vervolgens Base-64 gecodeerd en verstuurd naar de server. Als je identiteit voldoende rechten heeft, krijg je vervolgens toegang tot het opgevraagde bestand. Bij ieder volgend bestand dat je opvraagt, wordt je gebruikersnaam en wachtwoord meegestuurd, zodat je niet voor ieder bestand je gegevens opnieuw hoeft in te voeren. Het voordeel van Basic Authentication is dat vrijwel iedere browser het ondersteunt. Het nadeel is echter dat Base-64 codering niet versleuteld is, en het dus eenvoudig is om iemands gebruikersnaam en wachtwoord te onderscheppen, tenzij je een SSL verbinding hebt. Digest Authentication werkt volgens hetzelfde principe als Basic Authentication, met het belangrijkste verschil dat logingegevens versleuteld naar de server gestuurd worden. Je kunt daardoor veilig inloggen, ook al is de verbinding onveilig. Het nadeel van Digest Authentication is dat de meeste browsers het niet ondersteunen; Internet Explorer 5.0 en hoger ondersteunt Digest Authentication, alsmede Opera 6.0 en Mozilla 1.0, maar andere veel gebruikte browsers niet. Een ander probleem is dat op dit moment de verschillende implementaties van Digest Authentication niet 100% compatibel zijn.

Integrated Windows Authentication werkt in principe alleen op een lokaal netwerk, omdat het geen gebruik maakt van HTTP en toegang nodig heeft tot de domein controller om de identiteit van de aanvrager te toetsen. Dit werkt dus niet als er een firewall tussen de browser en de web server staat. Een voordeel van Integrated Windows Authentication is dat de gebruiker in principe geen gebruikersnaam en password op hoeft te geven, omdat de identiteit wordt gebruikt waaronder de gebruiker ingelogd is op een computer in het domein. SSL Certificate Authentication vereist digitale certificaten en is daarom ook maar beperkt bruikbaar.
Het uiteindelijke resultaat van de verschillende identificatiemethodes is hetzelfde: het Windows NT account en dus de identiteit van de gebruiker is bekend. ACLs bepalen vervolgens of een gebruiker toegang heeft tot opgevraagde bestanden.
Maar wat gebeurt er nu als een website vrij toegankelijk is? Er wordt dan geen identiteit vastgesteld, dus weet de server ook niet welk account er gebruikt moet worden om bestanden te openen. Er wordt daarom wel van Anonymous Access gesproken. Omdat zonder account een ACL geen toegang geeft tot een bestand (en niemand dus toegang zou krijgen in plaats van iedereen), gebruikt IIS een speciaal account dat wordt aangemaakt als IIS geïnstalleerd wordt: het IUSR_machinenaam account. Hierbij is de machinenaam de Netbios naam van de web server. Alle anonieme aanvragen worden gedaan onder de identiteit van het IUSR account. Dit account heeft slechts beperkte rechten, en elk bestand dat via Anonymous Access toegankelijk moet zijn, moet dus toegang verlenen aan dit account of een groep waar dit account deel van uit maakt. Een ASP pagina die opgevraagd wordt onder Anonymous Access, moet dus toegankelijk zijn voor het IUSR account. De pagina zelf wordt echter opgevraagd of uitgevoerd door IIS zelf (inetinfo.exe) dat draait onder het SYSTEM account. Dit account heeft toegang tot vrijwel alle resources op de web server zelf, maar geen toegang tot het netwerk. Deze situatie is over het algemeen onwenselijk, omdat misbruik van het SYSTEM account toegang geeft tot de hele server. Ook wil het nog wel eens nodig zijn om resources op het netwerk te benaderen, waarvoor een geldig domein account nodig is. Je kunt dit verhelpen door te werken met WCS (voor meer informatie over ASP en WCS zie Onder welke gebruiker werkt een script?.

ASP.NET beveiligingsmodel

ASP.NET opereert grotendeels los van IIS. IIS fungeert als een doorgeefluik voor ASP.NET pagina's die worden opgevraagd. ASP.NET (aspnet_wp.exe) werkt in een apart proces onder een account dat te vergelijken is met het IUSR account, het ASPNET account. Dit account is onderdeel van de NT groep Users en heeft daardoor betrekkelijk weinig rechten. Hoewel ASP.NET en IIS in verschillende processen werken, geeft IIS niet alleen de aanvraag voor een bestand door, maar ook de gebruiker waaronder de aanvraag gedaan wordt. Dit is de gebrukker die geïdentificeerd is via een van de identificatiemethodes, of het IUSR account. ASP.NET gebruikt dit account om te kijken of de gebruiker het opgevraagde pagina uit mag voeren. Mag de pagina uitgevoerd worden, dan wordt standaard de pagina uitgevoerd onder het ASPNET account (in plaats van het SYSTEM account in het geval van IIS). Het ASPNET account moet dus toegang hebben tot de benodigde bestanden en resources wil de pagina goed uitgevoerd worden. Omdat het ASPNET account weinig rechten heeft, is misbruik van dit account veel minder ernstig. Het aardige van ASP.NET is dat je de gebruiker waaronder ASP.NET pagina's uitvoert kunt veranderen. Zoals gezegd worden ASP.NET pagina's standaard uitgevoerd onder het ASPNET account. Je kunt via machine.config ASP.NET echter ook zo instellen dat het pagina's uitvoert onder een ander account. Let erop dat als je dit doet dat dit behoorlijke implicaties heeft voor de beveiliging. Als de mogelijkheden van een account groter zijn, zijn de mogelijkheden voor misbruik ook groter. Helaas kun je dit alleen op machine niveau doen en niet op applicatie niveau. Wil je ASP.NET onder het SYSTEM account laten werken, dan moet in machine.config

<processModel userName="machine" ... />

veranderen in

<processModel userName="SYSTEM" ... />

Er zijn veel meer attributen (aangegeven door ...) maar die zijn op dit moment niet relevant. Je kunt ook een domein account gebruiken indien er toegang nodig is tot het netwerk (hoewel er andere manieren zijn om dit te bewerkstelligen) door machine.config als volgt aan te passen:

<processModel userName="domein\gebruiker"
              password="wachtwoord" />

Over het algemeen is het slimmer om de gebruiker waaronder pagina's worden uitgevoerd te veranderen door middel van impersonation. Op die manier werkt de pagina in feite nog onder het account dat aangegeven wordt bij processModel, maar simuleert het een ander account. Impersonation kun je instellen op applicatieniveau, hetgeen beter is dan instellingen die alleen in machine.config gedaan kunnen worden. Als je impersonation aan zet heb je twee mogelijkheden; je kunt een vaste gebruiker instellen, of je kunt ASP.NET gebruik laten maken van het account dat IIS doorgeeft (ter herinnering, een door IIS ingelogde gebruiker, of het IUSR account). Dit laatste kun je doen door web.config in de hoofdmap van de applicatie aan te passen zodat het er als volgt uit ziet:

<configuration>
  <system.web>
    <identity impersonate="true" />
    ...
  </system.web>
</configuration>

Wil je dat de applicatie gebruik maakt van een specifiek account, dan kun je een gebruikersnaam en een wachtwoord toevoegen:

<identity impersonate="true"
          userName="domein\gebruiker"
          password="wachtwoord" />

Het beveiligingsmodel van ASP.NET zoals tot nog toe gepresenteerd is redelijk complex. Welke gebruiker er nu precies gebruikt wordt om een pagina uit te voeren is niet zo 1-2-3 duidelijk. Om het makkelijker te maken geeft Figuur 1 een schematische weergave van de procedure die gevolgd wordt. Noot: Of code onder het ASPNET account uitgevoerd wordt hangt af van de instelling van de processModel gebruiker.


Figuur 1, Overzicht beveiligingsmodel ASP.NET

Autorisatie op basis van URLs

Tot nog toe ging alle autorisatie op basis van ACLs op bestanden. Je kunt echter ook autoriseren op basis van URLs en de ACLs negeren. De ACL moet wel nog steeds toegang verlenen aan het ASPNET account, want anders kan de pagina überhaupt niet uitgevoerd worden. Je kunt URL autorisatie instellen in web.config. Het voordeel hiervan is dat je toegang tot bestanden kunt regelen in web.config, in plaats van dat je ACLs moet instellen voor bestanden. Zeker als je geen directe toegang hebt tot de server kan dat laatste moeilijk te realiseren zijn. Het nadeel is echter dat je alleen ASP.NET pagina's kunt beveiligen, omdat HTML pagina's, plaatjes, enz. Niet door ASP.NET maar door IIS worden afgehandeld. URL autorisatie werkt per map, waarbij een web.config bestand in een submap de instellingen van de hoofdmap overschrijft. Staan er geen autorisatie instellingen in web.config in de submap (of helemaal geen web.config), dan neemt de submap de instellingen over van de map erboven. Wanneer je URL autorisatie gebruikt in combinatie met Windows identificatie, moet je de gebruiker inclusief domeinnaam aangeven. Een web.config bestand dat toegang geeft tot alle ingelogde gebruikers ziet er als volgt uit:

<configuration>
  <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
    ...
  </system.web>
</configuration>

Het ? in de code hierboven wordt gebruikt om aan ASP.NET aan te geven dat alleen ingelogde gebruikers toegang hebben. Een * betekent alle gebruikers (ingelogd of niet). Als je het authorization element als volgt aanpast, krijgen alleen Michiel en Peter (in domein ASPNL) toegang tot de map. Alle andere gebruikers krijgen geen toegang.

<authorization>
  <allow users="ASPNL\Michiel, ASPNL\Peter" />
  <deny users="*" />
</authorization>

Je kunt meerdere allow en deny elementen gebruiken, met dien verstande dat de bovenste elementen het sterkst zijn. Als je dus in plaats van hierboven de volgende instelling gebruikt

<authorization>
  <deny users="*" />
  <allow users="ASPNL\Michiel, ASPNL\Peter" />
</authorization>

krijgen ook Michiel en Peter geen toegang tot de map, ondanks dat ze wel genoemd worden in een allow element. Je kunt verder ook op basis van groepen in plaats van individuele gebruikers werken. Als je toegang wil geven aan de groep Ontwikkelaars met uitzondering van Peter, dan ziet web.config er als volgt uit:

<authorization>
  <deny users="ASPNL\Peter" />
  <allow roles="ASPNL\Ontwikkelaars" />
  <deny users="*" />
</authorization>

Als laatste kun je ook beveiligen op basis van de verschillende soorten HTTP verbs (GET, POST, en HEAD). Als je wilt zorgen dat anonieme gebruikers geen POST (versturen gegevens via formulier) mogen uitvoeren, kun je dit als volgt aangeven in web.config:

<authorization>
  <deny verb="POST" users="?" />
</authorization>

Conclusie

Het beveiligen van een web applicatie an sich is niet erg ingewikkeld. Je kunt kiezen uit ACL en URL autorisatie, en beide zijn makkelijk te gebruiken. De details die bepalen onder welk account een pagina nu eigenlijk uitgevoerd wordt zijn echter behoorlijk complex, en kunnen vaak voor verwarring zorgen, omdat je in sommige gevallen zou denken dat iemand geen toegang heeft, maar dat toch blijkt te hebben (of andersom). Er gaat daarom niets boven het goed testen van de beveiligingsinstellingen voordat je ze daadwerkelijk gebruikt. Een kleine test applicatie (download) laat een aantal details zien waar je rekening mee moet houden.

Dit artikel is eerder verschenen in Windows & .NET Magazine Benelux, juni 2002 (huidige naam: NetOpus)

<< vorige | ^ naar boven | overzicht | volgende >>
copyright 2000-2007 ASPNL