Tag Archives: ASP.NET

IIS 6/ASP.NET 2.0 Security Demystified – Part 1

This week I have been working on a custom security module for ASP.NET
2.0 (you mean to say that Windows authentication and Forms
authentication is not enough?).   My development process has
involved wading through .NET Framework security code (thanks to Lutz Roeder for Reflector), and
reading articles on IIS (Internet Information Server) security in MSDN Magazine (just so happens that
this month’s issue is all about security). 

Understanding computer security can be a tough nut to crack, and I’ll
be the first to admit that I am not an expert on this
subject. This post is the first of a few, containing bits of
information from the various articles I have read, and findings from
development of the above mentioned custom security module. 

Before you get too engrossed in my post, I should mention that the posts in this
series contain overview information.  If you’re looking for
in depth knowledge into IIS/ASP.NET security models, then I would
recommend reading one of the many books published on this subject.

Let’s start this first post with an overview of the security components.  The image below, from the latest MSDN publication,
defines the component parts involved with IIS 6/ASP.NET 2.0 security.



That many components involved in IIS/ASP.NET security – who knew?

The above image mentions most of the active security components involved in the
security process of an ASP.NET web request, I’ll discuss a subset of
the components briefly: 

The http.sys driver is responsible for processing the incoming request at a low level in IIS, and passing the request to the w3wp.exe worker process – the process that does all the work in IIS (in version 5 of IIS, a separate process – aspnet_wp.exe – was launched to process ASP.NET web requests, in IIS 6 the process is part of the IIS worker process). 

The SSL Requirement module handles all incoming  SSL requests, and
the IP Restrictions module filters requests based on IP address ranges.


Authentication
and Authorization modules handle authentication of a
particular user issuing the web request, and authorized access to the
requested web resource.

The Extension Restrictions module restricts access to certain file types, based on the file type extension.

The aspnet_filter.dll is a small ISAPI library used to backup
the cookie-less session state for ASP.NET, and also filters requests for
protected files in web application bin directories.

The aspnet_isapi.dll is the main ISAPI library for ASP.NET,
which hosts a instance of the .NET Framework CLR (Common Language
Runtime), and is responsible for execution of all ASP.NET web
applications.

ASP.NET also adds it’s own level of security when processing web
requests.  The Authentication module and Authorization module look
after user authentication and authorized access to protected web resources
for each ASP.NET application.

Finally the handler mapper is responsible for executing, framework supplied and custom HTTP Handlers and HTTP Modules.

Each of the modules, mentioned above, deserves a post in it’s own right to provide
enough knowledge on their inner workings.  Instead, I have
attempted to provide a snapshot from 30,000ft of each component, and
part that each plays in securing web requests.  My next post will
be concerned with the various authentication options in IIS.

Event catch-up in ASP.NET 2.0 Controls

Pop quiz, what is wrong with the following class?

public class MyPlaceHolder : PlaceHolder
{
protected override void OnInit(EventArgs e)
{
Page.Trace.Write(this.ID, “In OnInit”);
base.OnInit(e);
}

protected override void OnLoad(EventArgs e)
{
Page.Trace.Write(this.ID, “In OnLoad”);
base.OnLoad(e);
}

protected override void OnUnload(EventArgs e)
{
Page.Trace.Write(this.ID, “In OnUnload”);
base.OnUnload(e);
}

protected override void OnPreRender(EventArgs e)
{
DropDownList myDropDownList1 = new DropDownList();
myDropDownList1.ID = “_myDropDownListDynamic1”;
myDropDownList1.Items.Add(new ListItem(“One”, “one”));
myDropDownList1.Items.Add(new ListItem(“Two”, “two”));
this.Controls.Add(myDropDownList1);
base.OnPreRender(e);
}
}

The class above is a custom server control that derives from an ASP.NET
PlaceHolder control.  This example is a stripped down version of a
class I am currently working on this week (which loads controls
dynamically from custom XML).  I chose the PlaceHolder control to
derive from because I needed a container control, in which to hold my
dynamically instantiated controls – the PlaceHolder control is designed for,
and ideal for this purpose.

I ran into a problem with persistence of property values belonging to
dynamic controls when contained in my custom MyPlaceHolder
control.  In the above example I have created a DropDownList
control dynamically in the OnPreRender method, and added it to the
controls collection of MyPlaceHolder, which, as it turns out is a problem…..

Those of you who know enough about how ASP.NET works (1.1 and 2.0), will know about “catch-up”:

When controls are declared statically in an ASPX page, ASP.NET
instantiates these controls, adds them to an in-memory control tree,
and then calls various event methods on each control, and child
controls recursively, before the page is rendered.  (I have
included the order of events of all controls in ASP.NET later in this
post).

When a control is created dynamically, the time in which the control is
instantiated is at the mercy of the developer. For this reason, ASP.NET
plays “catch-up” and arranges to call all missed event methods so that
the control is in sync with it’s container. Using the above code as an
example – after instantiating the drop down list control and adding this
control to the controls collection of the placeholder, ASP.NET will
call the OnInit, LoadViewState, and OnLoad event methods of the drop down list control,
after which the drop down list control will have caught up to the pre-render event of the
placeholder container.

So, why do I loose persistence of property values in my drop down list control, specifically the selected index property? 

When ASP.NET plays “catch up”, the framework will call some, or all of
the OnInit, LoadViewState, OnLoad, and OnPreRender methods, depending
on the current state of the containing control.  The methods to process post back data are not called during catch-up.

The following AddedControl method exists as part of the Control class
in the ASP.NET 2.0 framework (version 1.1 will have similar code), and
demonstrates “catch-up”, using the current state of the control. Notice
that no call exists to load post data.

protected internal virtual void AddedControl(Control control, int index)
{
if (control.OwnerControl != null)
{
throw new InvalidOperationException(SR.GetString(“Substitution_NotAllowed”));
}
if (control._parent != null)
{
control._parent.Controls.Remove(control);
}
control._parent = this;
control._page = this.Page;
control.flags.Clear(0x20000);
Control control1 = this.flags[0x80] ? this : this._namingContainer;
if (control1 != null)
{
control._namingContainer = control1;
if ((control._id == null) && !control.flags[0x40])
{
control.GenerateAutomaticID();
}
else if ((control._id != null) || ((control._occasionalFields != null) && (control._occasionalFields.Controls != null)))
{
control1.DirtyNameTable();
}
}
if (this._controlState >= ControlState.ChildrenInitialized)
{
control.InitRecursive(control1);
if (((control._controlState == ControlState.Initialized) && (control.RareFields != null)) && control.RareFields.RequiredControlState)
{
this.Page.RegisterRequiresControlState(control);
}
if (this._controlState >= ControlState.ViewStateLoaded)
{
object obj1 = null;
if ((this._occasionalFields != null) && (this._occasionalFields.ControlsViewState != null))
{
obj1 = this._occasionalFields.ControlsViewState[index];
if (this.LoadViewStateByID)
{
control.EnsureID();
obj1 = this._occasionalFields.ControlsViewState[control.ID];
this._occasionalFields.ControlsViewState.Remove(control.ID);
}
else
{
obj1 = this._occasionalFields.ControlsViewState[index];
this._occasionalFields.ControlsViewState.Remove(index);
}
}
control.LoadViewStateRecursive(obj1);
if (this._controlState >= ControlState.Loaded)
{
control.LoadRecursive();
if (this._controlState >= ControlState.PreRendered)
{
control.PreRenderRecursiveInternal();
}
}
}
}
}

My drop down list box  looses persistence because, by the time the
control is instantiated at the pre-render stage, the time for loading
post back data has passed. 

Loading of post back data is in fact performed by the Page class in the
ProcessPostData method, which is called twice by the ProcessRequestMain
method – once before the OnLoad method (before OnPreLoad in ASP.NET
2.0), and again (if not called prior) just after the OnLoad method
completes. This loading of post data before and after OnLoad allows the
developer to add dynamic control instantiation code in the most derived
version of OnLoad method without having to worry about when the base
version is called.

More details about event “catch-up” can be on this excellent post. Also,
check out the Page.ProcessRequestMain, Page.ProcessPostData and
Control.AddedControl methods in the framework using Lutz Roeder’s
Reflector
.

As promised earlier, here is a list of the event methods called by ASP.NET 2.0 in a page render life cycle:

Page Life cycle methods in ASP.NET 2.0

Method Active
Constructor Always
Construct Always
TestDeviceFilter Always
AddParsedSubObject Always
DeterminePostBackMode Always
OnPreInit Always
LoadPersonalizationData Always
InitializeThemes Always
OnInit Always
ApplyControlSkin Always
ApplyPersonalization Always
OnInitComplete Always
LoadPageStateFromPersistenceMedium PostBack
LoadControlState PostBack
LoadViewState PostBack
ProcessPostData1 PostBack
OnPreLoad Always
OnLoad Always
ProcessPostData2 PostBack
RaiseChangedEvents PostBack
RaisePostBackEvent PostBack
OnLoadComplete Always
OnPreRender Always
OnPreRenderComplete Always
SavePersonalizationData Always
SaveControlState Always
SaveViewState Always
SavePageStateToPersistenceMedium Always
Render Always
OnUnload Always

IPostBackDataHandler and IPostBackEventHandler

I’ve been messing around with post back handler in ASP.NET today, and I
found out a few points of interest.  Firstly, a description of the
two interfaces used with server controls to handle post backs:

IPostBackEventHandler – Implemented by server controls that wish to handle post back events. The RaisePostBackEvent
method is invoked by the framework when the control that implements
this interface method is the source of a page post back – such as a
submit button.  The RaisePostBackEvent method is expected to call an event delegate on the control, suck as Click.

IPostBackDataHandler – Implemented by server controls that wish to handle posted form data state changes. The LoadPostData
method is invoked by the framework when the control that implements the
interface method has posted some form data.  This method should
compare the posted data (contained in a NameValueCollection, keyed with
a passed unique post data key) with the data internal to the control,
to see if the user changed the data on the page.  This method is
expected to return true if the state of the data has changed.  The
framework checks to return value of LoadPostData and calls the
RaisePostDataChangedEvent method if the return value was true.  The RaisePostDataChangedEvent methods is expected to call a changed event delegate on the control.

Below is is the source code to a couple of server controls that I had implemented to test these interfaces. 

public class MyButton : Control, IPostBackEventHandler
{
public string Text
{
get { return ViewState[“myText”] as string; }
set { ViewState[“myText”] = value; }
}

public delegate void ClickHandler(object sender);

public event ClickHandler Click;

public MyButton()
{

}

#region IPostBackEventHandler Members

public void RaisePostBackEvent(string eventArgument)
{
string res = eventArgument;
if (null != Click)
Click(this);

}

#endregion

protected override void Render(HtmlTextWriter writer)
{
writer.WriteLine(“”);
}

}

public class MyTB : Control, IPostBackDataHandler
{
private string VSID
{
get { return “myText” + this.UniqueID; }
}

public string Text
{
get { return ViewState[VSID] as string; }
set { ViewState[VSID] = value; }
}

public delegate void ChangedHandler(object sender);

public event ChangedHandler Changed;

#region IPostBackDataHandler Members

public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection values)
{
String presentValue = Text;
String postedValue = values[postDataKey];
if (!presentValue.Equals(postedValue))
{
Text = postedValue;
return true;
}
return false;
}

public void RaisePostDataChangedEvent()
{
if (null != Changed)
Changed(this);
}

#endregion

protected override void Render(HtmlTextWriter writer)
{
writer.WriteLine(“”);
}
}

Point #1:  Initially both controls were not working.  After
pulling out some hair, I figured out that each rendered control must
output a “name” attribute with a unique value. Without this attribute
the framework has no way of calling either the RaisePostBackEvent or LoadPostData
methods on the correct control instance. Adding an ID field is not
enough, for some reason ASP.NET insists on the “name” attribute.

Point #2: IPostBackDataHandler
makes no sense on controls that do not change their state between page
posts – duh.  Sounds obvious, but that still did not stop me
spending 20 minutes trying to figure out why this interface was not
working on my custom button control. 

Point #3: I wanted to know why the string argument passed to the RaisePostBackEvent
method was null when I rendered my custom button as a regular HTML form
submit button. Even though a simple submit button will cause a post
back or sort – after all a post back is essentially a form submission –
the framework will not interpret the form submit as a true post back
without the __doPostBack JavaScript call.  This JavaScript method
has the capacity to pass an argument to the framework during a form a
post.  Adding this method to my code was a simple case of
rendering the returned string from the GetPostBackEventReference method in an “onclick” attribute.

Point #4: When comparing posted data with that of the internal state of
the data in the control, using LoadPostData,
it helps if the control persists state
of its own data in the first place.  For example, when persisting
the text value in my custom text box I used the ViewState. Had I used a
private member variable to store the internal text value, the
persistence would have been lost for each post back; because a new
instance of each control on the page is loaded for each page request.

ViewState Tracking in ASP.NET Controls

Let’s say you have the following snippet of code below. The code
dynamically
instantiates a new ASP.NET control, changes the title property and then
adds the control to the control collection of a placeholder on the
page – a typical approach to dynamically creating controls.  When
the control loads, it adds an item into the drop down list
items collection with the same name as the current title property
value.  The title property of the control stores it’s value in the
ViewState, so that the title value is retained between page post
backs.  The problem is, this code does not work as expected. After
a post back the value of the title property is lost – why?

using System;
using System.Web.UI.WebControls;
using System.Collections.Generic;

public class MyDropDownList : DropDownList
{
public string Title
{
get { return ViewState[“myTitle”] as string; }
set { ViewState[“myTitle”] = value; }
}

protected override void OnLoad(EventArgs e)
{
this.Items.Clear();
this.Items.Add(new ListItem(Title));
}
}

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MyDropDownList ctrl = new MyDropDownList();
ctrl.Title = “Hello World!”;
myPlaceHolder.Controls.Add(ctrl);
}
else
{
MyDropDownList ctrl = new MyDropDownList();
// No need to assign title as it should be in the viewstate – right?
myPlaceHolder.Controls.Add(ctrl);
}
}
}

Finding the answer to this problem took some digging buy a co-worker –
The problem occurs because the control is not tracked by the ViewState
until the control is added to the parent container’s control
collection. Once the control is added to the control collection of the
placeholder, ViewState tracking is turned on and changes to the title
property are then stored in the ViewState.  In the above example, the
title of the control was assigned before the control was added to the
placeholder control collection, so the ViewState had not tracked a
change to the title, and therefore did not persist the value.

When dynamically creating user or server controls in ASP.NET always add
the control to the container controls collection before manipulating
the ViewState
.

The code below fixes the problem:

using System;
using System.Web.UI.WebControls;
using System.Collections.Generic;

public class MyDropDownList : DropDownList
{
public string Title
{
get { return ViewState[“myTitle”] as string; }
set { ViewState[“myTitle”] = value; }
}

protected override void OnLoad(EventArgs e)
{
this.Items.Clear();
this.Items.Add(new ListItem(Title));
}
}

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
MyDropDownList ctrl = new MyDropDownList();
// Add the control to the placeholder controls collection to enable ViewState tracking.
myPlaceHolder.Controls.Add(ctrl);
ctrl.Title = “Hello World!”;
}
else
{
MyDropDownList ctrl = new MyDropDownList();
myPlaceHolder.Controls.Add(ctrl);
}
}
}

ASP.NET Execution Process

In my previous post I mentioned the steps involved in the process of an ASP.NET page. As promised, here are the details on the slide that was covered in Chris Mazzanti’s presentation at this months Rockville WinProteam user group meeting.

Firstly, all ASPX and ASCX pages are just serialized control trees – object structures. If you turn on tracing for your ASPX page (see image below) you can see the control tree, server side controls are listed and HTML controls are listed as literal controls. This is helpful to understand the steps outlined below.

Before I start with the steps, a quick mention of what the View State is. The View State is a property bag used to stored object / key pairs. The View State persists objects between server postbacks, which can then be accessed using a key from the a pair. View State persists the changed state of all controls on a page, as well as any objects added to the View State by the page developer, during the postback. This marvel is achieved by encoding the property bag as a base 64 encoded string into a hidden form variable, which is a transmitted along with rendered HTML to the client browser and later posted back to the server when the win form is submitted.

When the ASP.NET framework loads an ASPX or ASCX serialized page it immediately deserializes the page into a control tree. The following operations are executed using this object model:

Instantiate – Instantiation of the control tree, described.

Initialize – The Init event is fired and preliminary initialization of controls is started. Dynamic child controls of the page are typically loaded here.

Begin Tracking View State – ASP.NET starts monitoring changes to objects in the view state. Only objects in the View State that change (dirty objects) have their new state saved to the View State encoded output.

Load View State (Postback only) – The View State encoded string is loaded from the post data in the HTTP request.

Load Postback Data (Postback only) – Postback data for all controls loaded.

Load – The Load event is fired. Most developers know this step as the Page_Load method.

Raise Changed Events (Postback only) – Control events fired as a result of some data changed in the control on the client.

Raise Postback Events (Postback only) – Postback events fired (see Chris’s note on control events and postback events at the bottom of this post).

Prerender – The Prerender event is fired. Called before controls are rendered.

Save View State – The View State is saved as a base 64 encoded string.

Render – The RenderControl method of each control in the control tree is called and the output HTML is captured and packaged into the HTTP response, which is sent to the client browser.

Unload – The Unload event is fired.

Dispose – The control tree structure is released from memory and page execution is complete.

The above steps make it easier for developers to understand why certainly functionality is not possible in ASP.NET. For example, how many of us have tried to access the View State information for a control during the initialization step? Since the View State has not let been loaded yet, all controls still have their default value. Another hole that developers fall into (I did) is to attempt to manipulate the View State of a server control within the render step. The View State is already saved at this point, so any changes are pointless.

I want to thank Chris for presenting the above information in his presentation yesterday, it certainly cleared up some confusion with ASP.NET for me.

Here is Chris’s comments on the changed events and postback events steps:

In terms of PostBack events and Changed events, the differences are subtle. A “change” event is an event that a server control will raise during the postback phase if its data has changed while it was on the client. For example, you can have a TextBox generate a change event, and if the user changes the data in that control, the control will raise a data changed event during the postback phase.

It is important to keep in mind that these server side events are not the same as the event that generated the postback itself. For example, if you have a change event setup on a textbox control, simply changing the text will not (necessarily) cause the page to post back. However, if the user clicks the save button, the page will be posted to the server, the textbox will see that it’s data has changed, and fire a changed event. After all the changed events have fired, the “post back” event will fire. This is the event that is raise by the control that actually caused the page to the be sent back to the server in the first place.

View State Improvements in ASP.NET 2.0

http://msdn.microsoft.com/msdnmag/issues/04/10/View State/default.aspx

What is the View State?

The view state is a hidden form variable containing data encoded in base-64 to represent the state of server side controls on an ASP.NET page.

What’s wrong with the View State?

The view state can become large on pages that include a large number of controls, or complex controls like the DataGrid, that retain state. The view state is embedded in web pages posted to the browser. A large view state could significantly affect the responsiveness of an ASP.NET page if a large view state is downloaded and reposted for each round-trip.

Can the View State be turned off?

Yes, and in cases where no state is required, turning off state at the control level can reduce the size of the view state. However, some controls, such as the DataGrid control, use state to manage the operation of the control as well as the data associated with it. For example the DataGrid control uses the view state to control pagination.

Disabling the view state for some controls may affect post-back events. Text boxes and drop-down lists rely on the view state to determine if the content of the control has changed before firing a changed event.

Improvements in ASP.NET 2:

Serialization – The view state is binary serialized data, generated by each control retaining state, which is then encoded in base-64. ASP.NET 1.x used a number of less-than and greater-than characters to define field separation. ASP.NET 2 now uses single binary control characters, and requires fewer to encode the state of a control.

Base-64 adds a 30% overhead to serialized data.

Control State – The view state is now partitioned into two separate categories: control state and view state. The control state manages core behavioral functionality, whereas the view state is now only used to manage the controls content (UI). The control state is stored alongside the view state as base-64 in the hidden field, as before, only disabling the view state for a control will only disable the content management portion, retaining the control state for correct control behavior.

ASP.NET Vulnerability

This alert is to advise you of the availability of a web page that discusses an investigation Microsoft is currently conducting into public reports of a security vulnerability in ASP.NET. A malicious user could provide a specially-formed URL that could result in the unintended serving of secured content.

This alert is also to advise you of the availability of a new Microsoft Knowledge Base article: 887459. This article contains prescriptive guidance with steps customers can implement on their ASP.NET applications to help protect against a wide variety of malformed URL attacks.

Microsoft is providing this prescriptive guidance in order to inform customers as quickly as possible about the vulnerability and information on how to prevent an attack. Microsoft is actively investigating this issue and plans to release additional guidance and a security update to remedy the issue as soon as possible.
The Microsoft Knowledge Base article can be viewed here: http://support.microsoft.com/?kbid=887459

The web page that discusses the current investigation into the public reports of a vulnerability in ASP.Net can be viewed here: http://www.microsoft.com/security/incident/aspnet.mspx [ASP.Net Forums]