My blog has moved and can now be found at http://blog.aniljohn.com

No action is needed on your part if you are already subscribed to this blog via e-mail or its syndication feed.

Saturday, October 9, 2004
« Dual Monitor setup without a second moni... | Main | Password Memorability and Security »

It has been interesting to me to see the recent ASP.NET vulnerability play out.  One of the main factors that came into focus for me was that most developers do not seem to consider the principal of Defense in Depth when it comes to writing privileged code.

Since an example speaks much louder than lectures, lets take the following case..

My web site is as follows:

\webroot
 - web.config
           \Camelot
                - ProtectedPage.aspx

My web.config has the following:

<location path="Camelot">
    <
system.web>
        <authorization>
            <allow roles="KnightsRoundTable" />
            <deny users="*" /> 
        <authorization>
    <system.web>
<location>

As you can see above, the web application is configured such that the only users who have access to the protected directory "Camelot" are members of the group "KnightsRoundTable".

The problem is that most people leave it at that.. That is NOT Enough!

At this point you are basically exposed when your authorization module is somehow bypassed. So let us take a look at some things you can do to apply the principle of Defense in Depth to ProtectedPage.aspx.

1) Restrict which users can call your code

One of the easiest ways to do this is to annotate your classes and methods with declarative principal permission demands to control which users can call your classes and class members. In the above example, I would do the following:

[System.Security.Permissions.PrincipalPermission
(System.Security.Permissions.SecurityAction.Demand,Role=@"KnightsRoundTable")]
public class ProtectedPage: System.Web.UI.Page
{

}

If anyone who is not in the KnightsRoundTable group tries to call this page, they will get the following error:

Security Exception
Exception Details: System.Security.SecurityException: Request for principal permission failed.

And if you've done right thing and set up a Default Redirect page for errors, they will not get a stack trace and will be redirected to a generic error page.

2) Protect against spoofed post backs.

void Page_Init (Object sender, EventArgs e)
{
    if (User.Identity.IsAuthenticated)
        ViewStateUserKey = User.Identity.Name;
}

What this does is key the view state to an individual using a unique value of your choice.  This option, which is only available in ASP.NET 1.1, is the Page.ViewStateUserKey. This needs to be applied in Page_Init because the key has to be provided to ASP.NET before view state is loaded.

3) Redirect if user is not authenticated

The third thing that I do in a protected page simply make sure that a user is authenticated before they are allowed to view any content.

private void Page_Load(object sender, System.EventArgs e)
{
    if (!User.Identity.IsAuthenticated)
        Response.Redirect("~/GoodBye.aspx",true);
}

The key point here is that I am not simply depending on just one thing here to protect this page but a layered defense. Hopefully if one thing fails, the others will protect the page. 

Oh, did I mention that I also extensively instrument my applications such that when someone does try to access a protected page, I log that activity and if the content of that page is sensitive enough, I may also send real time notification of attempted break-ins to an admin?

Paranoid? Perhaps.  But I also sleep a whole lot more soundly :-)

 

Tags:: Security
10/9/2004 5:39 PM Eastern Daylight Time  |  Comments [4]  |  Disclaimer  |  Permalink   
Sunday, May 8, 2005 12:06:43 AM (Eastern Daylight Time, UTC-04:00)
Robert Hurlbut's .Net Blog
Sunday, May 8, 2005 12:06:43 AM (Eastern Daylight Time, UTC-04:00)
Nice tips. The only problem I see in #1 is that will cause the security settings to be compiled with the code, making it harder to configure it. This should be aleviated in ASP.NET 2.0 if you put the base page class in the Code directory (BTW, would you do that considering all your security concerns?).
<br>
Sergio Pereira
Sunday, May 8, 2005 12:06:43 AM (Eastern Daylight Time, UTC-04:00)
Sergio... I agree with the bit about (1) causing the setting to be compiled into the code. But in my case I am willing to accept that trade-off in exchange for greater peace of mind. Especially given that in most cases, the Administrator group name may not change going forwared.. The individual members of that group may change, but the group probably will not.
<br>
<br>There is no right answer of course, but security is often about what you are willing to accept in return for greater peace of mind.
Anil John
Sunday, May 8, 2005 12:06:43 AM (Eastern Daylight Time, UTC-04:00)
SecureCoder by Anil John
Comments are closed.