ASP.NET VERSIONS: ALL
Fill the Gaps
Protecting Non-ASP.NET Content
By Don Kiely
ASP.NET has always had various security features to protect access to ASP.NET content: .aspx pages, Web services, etc. But a common requirement of Web sites is to protect other types of content as well, such as images, other multimedia files, archaic ASP pages, PDF files, HTML pages, and whatever else you might put on a site. It is all too easy to use ASP.NET s great security features and feel like your site is protected, but still have gaping holes that make much of your content freely available without any protection. Give it a try: Even if your site is entirely protected by, say, Forms authentication, you can navigate directly to an image file, for example, by typing in the path and file name as part of the URL. Unless, of course, you take steps to prevent it.
Fortunately, there are both IIS and ASP.NET ways to protect all your content. I ll discuss a few of them here. See the references at the end of this article for places to go for more information.
Before diving into the options, it is worthwhile to
quickly review the gauntlet that a Web request must go through before the
client receives the requested content. On Windows, HTTP requests are handled by
Internet Information Services. IIS has its own security infrastructure, such as
whether anonymous users can receive content or they have to have Windows
network credentials. If anonymous access is allowed, or if the user has proper
credentials with which to authenticate, IIS looks at the request and decides
how to handle it. If it s a static file, it usually will immediately send the
resource to the client. Otherwise it checks the list of configured ISAPI
filters based on file extension. For example, .asp files are mapped to asp.dll
in c:\windows\system32\inetsrv by default, and most ASP.NET files are mapped to
aspnet_isapi.dll in the c:\windows\microsoft.net\framework\
This is a gross simplification of the process, but will do for our purposes. Now let s look at some of the options you can use to protect content.
Map Content Files in IIS
The list of IIS file mappings is configurable. You can get to the list by going to the Web site s properties in Internet Services Manager, selecting the Virtual Directory tab, and clicking first the Configuration button, then the Mappings tab. Select the ISAPI filter and set the file extension including the leading dot as shown below, and that filter will handle requests for that type of resource on the Web site.
Now, whenever IIS receives a request for that type of file, it will pass the request on to the specified ISAPI filter, such as the ASP.NET filter. In that case, you can use regular ASP.NET security to protect access to the resource, such as Forms authentication.
A downside to this technique is that you have to create a mapping for every type of resource. If the site has dozens of file types, it takes some work to set up them all. Fortunately, in IIS 6 on Windows 2003 Server, there s another option, Wildcard Application Mapping. It s a new section at the bottom of the Mappings tab in Internet Services Manager, as shown below.
What s cool about wildcard application mapping is that it passes off the resource to the specified ISAPI filter for authentication. Once the client has run whatever authentication and authorization gauntlet you set for it, control is passed back to IIS, which then passes the Web request to the normal ISAPI filter. For example, say you wanted to implement ASP.NET Forms security for an archaic ASP application. You could define a wildcard mapping to the ASP.NET 2.0 ISAPI filter and use membership management and the cool new login stuff to take care of authorization. Once done, the requested ASP page is run by the regular ASP ISAPI filter as normal. This way, if an unauthenticated user directly requests an ASP page, they are redirected to the ASP.NET login page, then redirected back to the requested page when authenticated. This takes a little work to implement, but is way simpler than it was back in the days of ASP.NET 1.x or Windows 2000.
Another downside of this mapping technique is that there is a minor performance hit using this technique, because IIS and ASP.NET have to do extra processing for it to work. So test it before you use it to make sure that the hit isn t unacceptable.
If you want to make sure that a file is never directly available to a client, you can go one step further: Map the file using the ASP.NET ISAPI filter, then assign it to the HttpForbiddenHandler list. If you look at the list of IIS mappings for an ASP.NET application, you might be surprised to find some entries in the list: .csproj and .vbproj project files, and .config files. Why are these files mapped when you would never want a client to download them?
The answer is that this is how ASP.NET protects many of
its internal files. Take a look at the
Each of these file types has an entry in IIS mappings so that it is passed to ASP.NET to handle; but by assigning it to the HttpForbiddenHandler, ASP.NET will not return the file to the client. This is a bit drastic though, since there is then no way to deliver the file s content to the client. But it s a fine way to protect things that a client should never see.
Richard Dudley has come up with a clever variation of this technique to deliver protected content. Instead of adding each file type to the HttpForbiddenHandler, it involves selecting one of the already protected file types, such as .resources. Rename each of your files to add the .resources extension in addition to the regular extension, such as to rename MySecretFile.pdf to MySecretFile.pdf.resources. Then write some simple code to serve up the correct file upon request, renaming it to eliminate the extra extension. Check out the details on his blog (cited in the references at the end of this article).
There are a few other options for protecting non-ASP.NET content:
- You can store the files outside the Web site, and use Windows permissions to grant access to the ASP.NET process account, then write code to read the file and send them to the client. This may not be an option in a shared host environment, though.
- Rename static Web pages, such as .htm and .html, to .aspx. If there is no server-side code to run, the request will be passed to ASP.NET, which then delivers the content directly. A bit of a performance hit, but pretty minor on today s servers.
- Use a URL rewriter to block access to files. I ll have more to say about this technique in the near future.
I m sure there are other options that address specific application requirements. What methods have you used that fit a particular need?
Don Kiely, MVP, MCSD, is a senior technology consultant, building custom applications as well as providing business and technology consulting services. His development work involves tools such as SQL Server, Visual Basic, C#, ASP.NET, and Microsoft Office. He writes regularly for several trade journals, and trains developers in database and .NET technologies. You can reach Don at mailto:[email protected] and read his blog at http://www.sqljunkies.com/weblog/donkiely/.
- Securing Non-ASP.NET Files, which covers the IIS 6 wildcard application mapping (http://www.asp.net/QuickStart/aspnet/doc/tipstricks/default.aspx#securingnonaspnetcontent).
- Protect PDF, DOC and other file types with Forms Authentication (http://aspadvice.com/blogs/rjdudley/archive/2005/05/21/2595.aspx) and Protecting Files in Shared Hosting Environment (http://aspadvice.com/blogs/rjdudley/archive/2005/10/03/12984.aspx) by Richard Dudley. Very creative solutions.
- Using Forms Authentication to Protect non-ASP.NET Files by James Foster (http://www.dotnetcoders.com/web/Articles/ShowArticle.aspx?article=43).
- ASP.NET Forums (http://forums.asp.net). Lots of great discussions about securing Web pages and content.