Friday, May 22, 2009

Application, Page and Control events in ASP.NET

Page Events in Asp.Net 1.0/1.1
AbortTransaction.
CommitTransaction
DataBinding
Dispose
Error
Init
Load
PreRender
Unload

Page Events in ASP.Net 2.0
PreInit
Init
InitComplete
PreLoad
Load
LoadComplete
PreRender
PreRenderComplete
Unload

ASP.Net page events when master page included

When using master pages, the normal page event lifecycle is a little different. Here is the actual order:

Page: OnPreInit
MasterPageControl: OnInit
Control: OnInit
MasterPage: OnInit
Page: OnInit
Page: OnInitComplete
Page: LoadPageStateFromPersistenceMedium
Page: LoadViewState
MasterPage: LoadViewState
Page: OnPreLoad
Page: OnLoad
MasterPage: OnLoad
MasterPageControl: OnLoad
Control: OnLoad
OnXXX
MasterPage: OnBubbleEvent
Page: OnBubbleEvent
Page: OnLoadComplete
Page: OnPreRender
MasterPage: OnPreRender
MasterPageControl: OnPreRender
Control: OnPreRender
Page: OnPreRenderComplete
MasterPageControl: SaveControlState
Control: SaveControlState
Page: SaveViewState
MasterPage: SaveViewState
Page: SavePageStateToPersistenceMedium
Page: OnSaveStateComplete
MasterPageControl: OnUnload
Control: OnUnload
MasterPage: OnUnload
Page: OnUnload



Complete Flow Of Application,Control and Page Events

It appeared to me that they added a few things here and there to the Application, Page and Control lifecycle in ASP.NET v2.0. Curious, I whipped up some derived classes to output to a text file every time one of these events fired in the grand scheme of a request. I wired in the basic events then did overrides for everything that appeared to fire at some point. I think it's mostly complete, but the data binding events don't appear to fire unless you've got some data binding to do...

Application: BeginRequest
Application: PreAuthenticateRequest
Application: AuthenticateRequest
Application: PostAuthenticateRequest
Application: PreAuthorizeRequest
Application: AuthorizeRequest
Application: PostAuthorizeRequest
Application: PreResolveRequestCache
Application: ResolveRequestCache
Application: PostResolveRequestCache
Application: PreMapRequestHandler
Page: Construct
Application: PostMapRequestHandler
Application: PreAcquireRequestState
Application: AcquireReq uestState
Application: PostAcquireRequestState
Application: PreRequestHandlerExecute
Page: AddParsedSubObject
Page: CreateControlCollection
Page: AddedControl
Page: AddParsedSubObject
Page: AddedControl
Page: ResolveAdapter
Page: DeterminePostBackMode
Page: PreInit
Control: ResolveAdapter
Control: Init
Control: TrackViewState
Page: Init
Page: TrackViewState
Page: InitComplete
Page: LoadPageStateFromPersistenceMedium
Control: LoadViewState
Page: EnsureChildControls
Page: CreateChildControls
Page: PreLoad
Page: Load
Control: DataBind
Control: Load
Page: EnsureChildControls
Page: LoadComplete
Page: EnsureChildControls
Page: PreRender
Control: EnsureChildControls
Control: PreRender
Page: PreRenderComplete
Page: SaveViewState
Control: SaveViewState
Page: SaveViewState
Control: SaveViewState
Page: SavePageStateToPersistenceMedium
Page: SaveStateComplete
Page: CreateHtmlTextWriter
Page: RenderControl
Page: Render
Page: RenderChildren
Control: RenderControl
Page: VerifyRenderingInServerForm
Page: CreateHtmlTextWriter
Control: Unload
Control: Dispose
Page: Unload
Page: Dispose
Application: PostRequestHandlerExecute
Application: PreReleaseRequestState
Application: ReleaseRequestState
Application: PostReleaseRequestState
Application: PreUpdateRequestCache
Application: UpdateRequestCache
Application: PostUpdateRequestCache
Application: EndRequest
Application: PreSendRequestHeaders
Application: PreSendRequestContent

Thursday, May 21, 2009

. NET Type Safety

Introduction

Before going any further, let us first have a look at what is type safe code and why is it relevant to secure programming.Type safety is certainly one of the most confusing aspects for somebody learning .Net. When .Net was released, it had a tag attached claiming that the programs developed in .Net are more stable when compared to programs developed using VB or VC++. This just adds to the confusion if you do not understand type safety very well.

Type safety
Type safe code can access only the memory locations that it has permission to execute. Type safe code can never access any private members of an object. Type safe code ensures that objects are isolated from each other and are therefore safe for inadvertent or malicious corruption.CLR performs a mandatory type safety check, called verification, during JIT compilation. This is done by a tool called peverify.exe, which examines the Microsoft Intermediate Language and the metadata included in the assembly. If an assembly (or code) is successfully verified as type safe, it is called verifiably type safe code.The code is said to be verifiably type safe when any references to the types inside that code are strictly compatible with the types they are referring to.Code need no always be verifiably type safe. This is for the situations where you have both managed as well as un-safe code in the same assembly. Remember, un-safe code need no always be un-verifiable code.Though this is a mandatory process performed by the CLR, it can be skipped by providing necessary permissions to that assemblyCLR ensures that the type safe code does not end up in any undesirable situations like calling native or unmanaged code or performing any malicious operations.

What is Type Safety?
Type safe means preventing programs from accessing memory outside the bounds of an object's public properties A programming language is type safe when the language defines the behavior for when the programmer treats a value as a type to which it does not belong. Type safety requires that well-typed programs have no unspecified behavior (i.e., their semantics are complete). Languages such as C and C++, which allow programmers to access arbitrary memory locations, are not type safe. An unsafe programming language supports operations (such as accessing arbitrary memory locations), which are not defined in terms of the language semantics. Type safety is a property of the programming language, and not of the programs themselves. What is Type Safety?Type safe means preventing programs from accessing memory outside the bounds of an object's public properties A programming language is type safe when the language defines the behavior for when the programmer treats a value as a type to which it does not belong. Type safety requires that well-typed programs have no unspecified behavior (i.e., their semantics are complete). Languages such as C and C++, which allow programmers to access arbitrary memory locations, are not type safe. An unsafe programming language supports operations (such as accessing arbitrary memory locations), which are not defined in terms of the language semantics. Type safety is a property of the programming language, and not of the programs themselves.

How does Type Safety affect us?
1) Type-safe code accesses only the memory locations it is authorized to access.
2) For example, type-safe code cannot directly read values from another object's private fields or code areas.
3) It accesses types only in well-defined, allowable ways, thereby preventing overrun security breaches.
4) Type safety helps isolate objects from each other and therefore helps protect them from inadvertent or malicious corruption. 5) It also provides assurance that security restrictions on code can be reliably enforced.

Why is Type Safety Important?
1) Type-safety is important for assembly isolation and security enforcement.
2) When code is type- safe, the common language runtime can completely isolate assemblies from each other.
3) This isolation helps ensure that assemblies cannot adversely affect each other and it increases application reliability.
4) Type-safe components can execute safely in the same process even if they are trusted at different levels.

Writing Type-Safe Code
Type-safe code is code that accesses types only in well-defined, allowable ways. Given a valid object reference, type-safe code can access memory at fixed offsets corresponding to actual field members. However, if the code accesses memory at arbitrary offsets outside the range of memory that belongs to that object's publicly exposed fields, it is not type-safe.

How is Type Safety ensured?
The Common Language runtime manages code at execution time. It provides core services such as ‘memory management’, ‘thread management’ and remoting. It also enforces strict type safety and promotes security and robustness.
1) During just-in-time compilation, an optional verification process examines the metadata and intermediate language of a method to verify that they are type-safe.
2) If the code has permission to bypass verification, then this process is skipped.
3) The common language runtime manages code at execution time, providing core services such as memory management, thread management, and remoting, and enforces strict type safety and other forms of code accuracy that promote security and robustness.
Example:
double dblX=10.59;
int intY=5;
intY = dblX; / / this causes an Error

What is Verifiable Type Safe Code?
JIT compilation performs a process called verification that examines code and attempts to determine whether the code is type-safe.
Code that is proven during verification to be type-safe is called verifiably type- safe code.
Code can be type-safe, yet not be verifiably type-safe, due to the limitations of the verification process or of the compiler. Not all languages are type-safe, and some language compilers cannot generate verifiably type-safe managed code.

Verification process:
As part of compiling MSIL to native code, code must pass a verification process unless an administrator has established a security policy that allows code to bypass verification. Verification examines MSIL and metadata to find out whether the code is type safe, which means that it only accesses the memory locations it is authorized to access. The runtime relies on the fact that the following statements are true for code that is verifiably type safe:
a) A reference to a type is strictly compatible with the type being referenced
b) Only appropriately defined operations are invoked on an object
c) Identities are what they claim to be.
During the verification process, MSIL code is examined in an attempt to confirm that the code can access memory locations and call methods only through properly defined types.

Additionally, verification inspects code to determine whether the MSIL has been correctly generated, because incorrect MSIL can lead to a violation of the type safety rules. The verification process passes a well-defined set of type-safe code, and it passes only code that is type safe. However, some type-safe code might not pass verification because of limitations of the verification process, and some languages, by design, do not produce verifiably type-safe code. If type-safe code is required by security policy and the code does not pass verification, an exception is thrown when the code is run.

What if the Code is not verifiably type safe?
1) Code that is not verifiably type-safe can attempt to execute if security policy allows the code to bypass verification.
2) But because type-safety is an essential part of the runtime's mechanism for isolating assemblies, security cannot be reliably enforced if code violates the rules of type- safety.
3) By default, code that is not type-safe is only allowed to run if it originates from the local machine.
4) All code that is not type-safe must have been granted ‘SecurityPermission’ with the passed ‘enum’ member ‘SkipVerification’ to run.

Tools:
How to determine if the code is type safe? Some language compilers generate verifiably type-safe code only when you avoid certain language constructs. The .NET Framework SDK PEVerify tool can be used to determine whether the code is verifiably type-safe.

Usage of PEVerify.exe:
C:\>PEverify.exe
Microsoft (R) .NET Framework PE Verifier. Version 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.Usage:

PEverify [Options]

Options:
/IL Verify only the PE structure and IL
/MD Verify only the PE structure and MetaData
/UNIQUE Disregard repeating error codes
/HRESULT Display error codes in hex format
/CLOCK Measure and report verification times
/IGNORE=[,...] Ignore specified error codes
/IGNORE=@ Ignore error codes specified in
/QUIET Display only file and Status. Do not display all errors.
/VERBOSE Display additional info in IL verification error messages.
/NOLOGO Don't display product version and copyright info.

Note: By default, MD is verified and then if there were no errors, IL isverified. If /MD /IL options are specified, IL is verified even ifthere were MD verification errors.

Example:
C:\Test\bin\Debug>peverify Test.exe

Microsoft (R) .NET Framework PE Verifier. Version 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.

All Classes and Methods in test.exe Verified.

Code Sample:
//This code fails the verification
unsafe
{
int* ptr = (int*) 0;
*ptr = 1000;
}
C:\>peverify C:\Test\bin\Debug\Test.exe

Microsoft (R) .NET Framework PE Verifier. Version 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
[IL]: Error: [C:\Test\bin\Debug\Test.exe : Test.Program::Main][offset 0x00000004][found Native Int][expected unmanaged pointer] Unexpected type on the stack
.[IL]: Error: [C:\Test\bin\Debug\Test.exe : Test.Program::Main][offset 0x00000005] Unmanaged pointers are not a verifiable type.2 Errors Verifying Program.exe