Here’s a short guide for those who want to know some of the relevant security technology in the new IIS7 and ASP.NET.
- Attack Surface Reduction – even more locked down than IIS6 (default disabled)
- No more metabase – it’s all about applicationHost.config which can be stored centrally on a UNC share and shared among a web farm.
- Supports compatibility mode for IIS6 and “classic mode” ASP.NET
- Support for PHP and Perl via FastCGI
- Delegated Admin to application owners.
Enough about those areas, let’s focus on these new things:
- Integrated Request Processing Pipeline
- ASP.NET integration right smack in the pipeline
- REQUEST FILTERING (REPLACES URLSCAN)
- IIS7 URL AUTHORIZATION
- USING ENCRYPTION TO PROTECT PASSWORDS
- THE STAGES OF A REQUEST/RESPONSE – SERVER PIPELINE
NEW Integrated request processing pipeline and WCF
The integrated request processing pipeline architecture is a huge improvement. It used to be effectively two separate server pipelines, making it near impossible for ASP.NET developers to interact with the HTTP pipeline as they’d like to do.
Windows process Activation Service (WAS) now handles communication between listener adapters and application pools. WCF (Windows Communication Foundation) everywhere – WCF services can be hosted anywhere, in a console app, a forms app, a WPF UI, and:
- IIS can host non-HTTP services, utilizing WCF through
- Look forward to a lot of web services over net.tcp (think Silverlight and .Net 3.5)
The IIS6 Model:
The IIS7 Model – WAS starts up w3wp.exe and handles messaging. The following diagram illustrates the changes.
Custom Modules can extend or replace IIS functionality (replaces old ISAPI model) – such as replacing the Basic auth module with a custom authentication provider. These dll’s get stored in %WinDir%\System32\Inetsrv.
In IIS 6, HTTP modules could only be written in managed code and could only process ASP.NET requests. In IIS7, modules can be written in native code, and process any Web requests.
NEW ASP.NET Integration
ASP.NET now plugged right into the server pipeline, no more hanging off the ISAPI engine. Basically developers now have tons of power to extend request/response processing that wasn’t possible before. ASP.NET has been set free.
New collections ASP.NET now has access to:
Leveraging Integrated ASP.NET mode:
- Forms-auth, Membership and Role-mapping
- ASP.NET modules and functionality now available to all content, used to be only aspx pages and other ASP.NET content-types.
Check for “preconditions” that limit ASP.NET functionality to only managed handlers.
<modules> <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" preCondition="managedHandler" /> <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />
Now if you remove the “precondition” (set by default) you can ensure AuthN and AuthZ is enforced for all content in the application. Otherwise only managed modules are handled.
NEW Request filtering (replaces URLScan)
Here’s a config to 1) normalize URL’s by disallowing double escaping, 2) disallow high bit characters, and 3) set a deny all file extension list.
These are set in the global applicationHost.config and can be overridden per application.
<fileExtensions allowUnlisted="true" > <add fileExtension=".asp" allowed="false"/> </fileExtensions> </requestFiltering> </security> </system.webServer></configuration>
Control things like:
- Which VERBs are allowed
- If double encoding allowed
- High-bit ASCII allowed or not
- File extensions allowed
- URL sequences (e.g. “..”) or use to set a default “deny all” policy and include explicit directories
Microsoft Ops story from dogfooding Microsoft.com the other week:
Gotcha for Microsoft.com: If filename includes “+” then allowDoubleEscaping must be set to “true“
Allow or disallow specific file extensions and verbs
<add fileExtension=”.exe” allowed=”false” />
<add sequence=”./” />
<add sequence=”/.” />
NEW IIS7 URL Authorization
Provides declarative access controls for the entire application – no code needed.
- Can be used with machine accounts or domain accounts
- Can be used with ASP.NET Membership and Roles and also for custom identities
- Stored in web.config files for easy distribution
- Can be configured through UI (not in ASP.NET UrlAuthorization)
- Implemented in assembly %windir%\System32\inetsrv\urlauthz.dll<add
- Applies to all content, not just .aspx or .asmx pages like the old ASP.NET UrlAuthorization
- ASP.NET UrlAuthorization was very developer focused, new IIS7 UrlAuthorization is more Administrator focused
Configuration section system.webServer/security/authorization – looks like:
<authorization lockElements="clear"> <add accessType="Deny" users="*" /></authorization>
- * = anonymous users ? = authenticated users
- Rules evaluated from Parent-level first, Deny rules first. With the lockElements=”clear” setting you force inheritance to lower levels so nobody can override the setting. * ASP.NET UrlAuthorization would evaluate from the bottom up, so this wouldn’t work.
NEW Using Encryption to Protect Passwords
WAS service runs as LOCALSYSTEM and needs access to identity passwords to launch Application Pools under. Still appears similar to IIS6 but there’s now a GUI and a different way of doing it. Basic steps:
- Create a new RSA key that only LOCALSYSTEM and Administrators have access to. This key will be used to encrypt passwords for every application pool. From the command line:createProvider.exe iisWasKey RsaKeyForWAS Rsa_WAS
- Create the application pools and encrypt their passwords. First set the default provider:setProvider.exe Rsa_WAS
Then configure the application pools to run with those accounts. Take a look at applicationHost.config and you’ll see the encrypted passwords.
- Lock down the encryption providers!!! By default IIS_IUSRS has read access to the keys when they are created. Remove that access so only LOCALSYSTEM and Administrators have access.cd /d %systemroot%
aspnet_regiis.exe -pr iisWasKey IIS_IUSRS
The stages of a request/response – Server Pipeline
The stages of the server pipeline, exposed as HttpApplication events in ASP.NET:
- BeginRequest. The request processing is starting.
- AuthenticateRequest. The request is being authenticated. IIS and ASP.NET authentication modules subscribe to this stage to perform authentication.
- AuthorizeRequest. The request is being authorized. IIS and ASP.NET authorization modules check whether the authenticated user has access to the resource being requested.
- ResolveRequestCache. Cache modules can check whether the response to this request exists in the cache, and return it instead of proceeding with the rest of the execution path. Both ASP.NET Output Cache and the new IIS Output Cache features execute here.
- MapRequestHandler. This stage is internal in ASP.NET, and is used to determine the request handler.
- AcquireRequestState. The state necessary for the request execution is being fetched. ASP.NET Session State, and Profile modules obtain their data here.
- PreExecuteRequestHandler. Any tasks before the execution of the handler can be performed here.
- ExecuteRequestHandler. The request handler executes here. ASPX pages, ASP pages, CGI programs, and static files are served here.
- ReleaseRequestState. The request state changes are saved, and the state is cleaned up here. ASP.NET Session State and Profile modules use this stage for cleanup.
- UpdateRequestCache. The response can be stored in the cache for future use here. The ASP.NET Output Cache and IIS Output Cache modules execute here to save the response to their caches.
- LogRequest. This stage is used to log the results of the request, and is guaranteed to execute even if errors occur.
- EndRequest. This stage is used to perform any final request cleanup, and is guaranteed to execute even if errors occur.
Checklist and Questions for Security Review
- Did you remove access to decryption keys so that only LOCALSYSTEM and Administrators have access?
- Did you remove the “precondition” so that ASP.NET AuthN and AuthZ applies to all content?
- Are you creating native code HTTP modules?
* is it Global or request-level
Are you creating a Hosted Web Core application?
* gets its own ApplicationHost.config separate from IIS
* it won’t inherit IIS process monitoring, health and recycling features
- Are you using the Runtime State and Control API (RSCA) for monitoring/management?
- Are you running a legacy application on IIS7?
- Dynamic Configuration – are you modifying system or application pool configurations in the code? (AppHostAdminLibrary)
IIS 7.0 Extend Your WCF Services Beyond HTTP With WAS