Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines

When you create a new ASP.NET MVC project using our default templates, one of the things you might notice is that there is a web.config file within the Views directory. This file is there specifically to block direct access to a view.

Let’s look at the relevant sections.

For IIS 6 (and Cassini)

<add path="*.aspx" verb="*" 
  type="System.Web.HttpNotFoundHandler"/>
 

For IIS 7

<add name="BlockViewHandler" path="*.aspx" verb="*" 
  preCondition="integratedMode" type="System.Web.HttpNotFoundHandler"/>

What these sections do is block all access to any file with the .aspx extension within the Views directory (or subdirectories). Note that access is blocked by mapping these file extensions to the HttpNotFoundHandler, so that a 404 error is returned when trying to access a view directly.

This works great if you are using all the ASP.NET MVC defaults, but what if you’re using an alternative view engine such as NHaml or NVelocity? It turns out you can directly request the view and see the code.

You’ll want to make sure to add extra lines within this web.config file with the appropriate file extensions. For example, if I were using NVelocity, I might add the following (in bold).

For IIS 6 (and Cassini)

<add path="*.aspx" verb="*" 
  type="System.Web.HttpNotFoundHandler"/>
<add path="*.vm" verb="*" 
  type="System.Web.HttpNotFoundHandler"/>
 

For IIS 7

<add name="BlockViewHandler" path="*.aspx" verb="*" 
  preCondition="integratedMode" type="System.Web.HttpNotFoundHandler"/>
<add name="BlockViewHandler" path="*.vm" verb="*" 
  preCondition="integratedMode" type="System.Web.HttpNotFoundHandler"/>

You might be wondering why we don’t block access to all files within the Views directory. Excellent question! In part, because the Views directory is a common place to put other static content such as images, pdfs, audio files, etc… and we decided not to prevent that option.

However, we’re open to suggestions. We do have a content directory in the default template. We could consider requiring putting static files in there or in another directory other than Views. I’m not sure how people would feel if they couldn’t put assets intended to support Views within the Views folder.

What others have said

Requesting Gravatar... Steven Harman Jun 25, 2008 11:39 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
w/r/t blocking direct access to everything in the /views/ directory... I don't feel too strongly one way or the other, but I don't think requiring someone using a custom view engine to add those web.config keys is a lot to expect. As long as that step is well understood, of course.

However, I totally get the argument for requiring all static content to live in the /content/ directory. Either way, I'd say pick a convention and go with it, allowing others to choose another route if/when they see fit.

Alternatives/choice is king! :)
Requesting Gravatar... mark Jun 25, 2008 12:40 PM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
Any way we can programmatically point to any view path in the controller? similar to the Page.LoadControl(string).
Or an attribute in the controller class that specify the location of the views for that controller.
I guess anything that is configurable and not static.

Thanks
Requesting Gravatar... haacked Jun 25, 2008 1:47 PM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
@Steven my concern is that while developing a custom view engine is a very advanced scenario, using one is not necessarily. And there's no way we can create an "affordance" that would indicate that if you're choosing to use this alternate view engine, you also need to remember to update web.config. That'll be something a LOT of people will forget.
Requesting Gravatar... Wyatt Barnett Jun 25, 2008 1:49 PM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
I'm squarely in the "static content belongs on a different domain, in a separate app and arguably on a different box" school of thought. So I wholeheartedly support limiting the /views folder to actual renderable views and pushing the content elsewhere.
Requesting Gravatar... Neal Blomfield Jun 25, 2008 2:06 PM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
My thinking may be a little backwards wrt ASP.NET MVC (I still use monorail), but isn't the views directory really a directory of templates through which the views are rendered and therefore shouldn't containing anything but templates?

IMHO use a content directory to separate stuff that the browser will request directly from the stuff that the browser will receive indirectly (the views).
Requesting Gravatar... Al Jun 25, 2008 4:19 PM
# Reluctant
I'd be reluctant to require people put files in a given place, if I want to put files under views - I thnk I should be able to.

I'd be more inclinded to make sure that sensible defaults are in place to stop accidents happening, ie by default it might be appropriate to block the views folder using a web.config option but if I choose to remove that, I'm doing so by my choice.
Requesting Gravatar... Lance Fisher Jun 25, 2008 4:38 PM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
I think it makes sense to put all static content in the content directory or on a different domain, and not in the Views directory. I didn't even realize you could put it there. If you blocked the views directory by default, I think it would help out the problem with showing empty Views during a debug. You know, F5, then you get an ASP.NET error because you're looking at a view page directly and not hitting the routing engine.

Go with the convention of putting static content in the content folder, and if the developer wants to change it to the views folder, he can modify the web.config. If he's using a different view engine, the new view engine should help him out with the configuration, or utilize the same convention.
Requesting Gravatar... John Walker Jun 26, 2008 12:10 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
I know there have been big changes in IIS7, but it concerns me a bit that the web.config file has to be different compared to IIS6. As the change from IIS6 to 7 occurs, there's sure to be some grief. Sorry for the non-MVC comment, but this is the first time I've grokked this as a possibility.
Requesting Gravatar... Boersnoes Jun 26, 2008 12:33 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
I vote Content folder. But at the same time, I feel some descent support should be provided out of the box to easely access this static content.
When you start using user controlls that don't know where they will be rendered in the file hierarchy on compile time, it is somewhat bothersome to reference the content folder (how many "../../" should I put?)
Currently I use a custom extention to the HTMLHelper I derived from a podcast (I think Rob's) that gives me a Html.CssUrl(cssName), a Html.PictureUrl(picName), a Html.JavaScriptUrl(jsUrl) etc.
Requesting Gravatar... Daniel Draper Jun 26, 2008 1:46 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
I think the view folder should contain just that "Views" any assets such as images, movies, audio, etc should be placed in the content folder. The content folder however should be broken into appropriate sub folders.

If you are worried about a relative path Boersnoes then just use the base tag or a custom funtion to acheive a similar outcome.

I think Al has a good point by making it optional but by default the programmer uses the content directory.
Requesting Gravatar... Dragan Panjkov Jun 26, 2008 4:13 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
I agree with others. Content folder should be used for static content. In this way Views could be reserved only for View files, independently of View Engine used, not to repeat others.
Requesting Gravatar... Ang3lFir3 Jun 26, 2008 8:31 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
I will have to agree with others that I strongly believe in keeping all my static content in the content folder or some other location. The Views folder to me is simply the location of the templates for rendering views. Also since many assets belong to many views its just easier for me to keep them organized in a single content location.

I am with Phil on the idea that using a custom view engine doesn't mean you will remember to take care of this step. The consiquences of not doing it make it dangerous.

+1 for restricting direct access to all files in the Views dir
Requesting Gravatar... Anders Jun 27, 2008 5:18 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
Another vote for restricting access to the views folder by default and having all the static content in the content folder.
Requesting Gravatar... Mark Brackett Jun 27, 2008 7:49 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
Another vote for disallowing the entire /Views directory by default. If someone wants to put content in there, then they can edit the web.config to allow it. That's much better than the security hole you're opening up for users of an alternative view engine.
Why wouldn't you use the existing location and deny tags to deny access? That'd return a 403-Unauthorized error (which is the correct one to choose here, IMO).
Requesting Gravatar... Andy Miller Jun 27, 2008 9:41 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
If you're going to get in the pool, get all the way in!

Years (...well...months anyway) of anecdotal evidence points to the answer: convention is better. Treat the Views directory just like the bin, App_Code, etc directories and block all access.
Requesting Gravatar... Damien Guard Jun 27, 2008 1:48 PM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
I'd go with whitelisting .gif, .jpg, .jpeg, .avi, .png, .mov, .mpeg, .css, .htc, .js in views and blocking everything else.

[)amien
Requesting Gravatar... EricTN Jul 02, 2008 7:36 PM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
I'm completely comfortable with the notion of: put all static content in the Content folder (in various subfolders as desired) and leaving the Views folder as a collection of View templates (at least *now* I'm comfortable with it - now that I've read the other comments above and moved all my content into Content).
Requesting Gravatar... Jahedur Rahman Aug 11, 2008 6:41 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
Hi, I want to allow http access to a swf file. How can I do that in ASP.Net MVC.
Requesting Gravatar... Michael Velasquez Aug 15, 2008 10:13 AM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
Hi, I have a question regarding blocking access to specific directories within the views directory.
Is there a way, other than specifying the role per action, to block access to specified directories under the views directory, based on role?

For instance, a web.config with the "BlockViewHandler" key copied into each directory that you'd like access blocked to?

Rather than blocking the entire views directory.
Requesting Gravatar... haacked Aug 15, 2008 12:49 PM
# re: Security Tip: Blocking Access to ASP.NET MVC Views Using Alternative View Engines
Yeah, you could copy our Web.config file we place within the Views directory and move it to the specific directories you want to block. You'll also have to specify which roles can have access. Lookup information on the element of web.config.

What do you have to say?

(will show your gravatar)
Please add 4 and 4 and type the answer here: