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)
|