Protecting Files in Shared Hosting Environment

In a previous post (http://aspadvice.com/blogs/rjdudley/archive/2005/05/21/2595.aspx), I showed one way to protect files from direct download by configuring IIS.  In a shared hosting environment, this usually isn’t possible, so I’ll show another way to protect these files.


First, a little review.  Out of the box, only certain file types are mapped to the ASP.NET ISAPI filter.  These include .aspx, .ascx, .ashx, etc.  If these pages are requested, IIS hands off processing to the ASP.NET filter.  Otherwise, IIS serves the file directly (or hands it off to another ISAPI, as necessary).  There are also a number of file types mapped to ASP.NET that are protected by the HttpForbiddenHandler.  This is an HTTP Handler that prevents direct download of files of the specified type.  If you examine the <httpHandler> section of your machine.config file, you’ll see the list.


It would seem that simply adding a file extension to the <httpHandler> section and have the HttpForbiddenHandler prevent its download would be great, but unfortunately, you need to also configure IIS for any new extention you want handled, which is the problem in the first place.


However, there’s a little trick we can use.  Let’s say you have a file named “protected.pdf” which you wish to prevent direct download of.  You can rename this file to “protected.pdf.resources”, and since the .resources extension is already forbidden, users will not be able to download this file directly even if they can guess the file name.  Try it and see.


When it comes time to allow users to download the file, you can use the System.Web.HttpResponse.WriteFile method to send the file to the user.  You may have to clear the response and add a content type to make this all work correctly, as shown:



strFileName = Server.MapPath(“protected.pdf.resources”)

strFileId = StrFileName.ToString.Replace(“.resources”, “”)


With HttpContext.Current.Response


   .ClearContent()


   .ClearHeaders()


   .ContentType = “application/pdf”


   .AddHeader(“Content-Disposition”, “inline; filename=” & strFileId)


   .WriteFile(strFileName)


   .End()


End With