Solved

ASP.Net trapping errors using web.config

Posted on 2010-09-23
14
897 Views
Last Modified: 2012-05-10
Hi,

I'm trying to trap errors in my ASP.net web app.
I started here http://support.microsoft.com/kb/306355
The article suggests  at least three ways of trapping and handling errors
1)Page_Error
2)Application_Error
3)Web.config

I want to write userID, page that caused error and Error message to the database and maybe generate an email to myself of the error( let's not worry about the last bit yet). I am using Visual Studios 2008 .

Keeping in mind the latest ASP.Net security issue I think I want to use option 3.
My question is when would I write error details to the database?
Is it in Application_Error? will Application_Error fire even though I'm using <customErrors> in web.config
Or do I write to the dB in the code-behind of the default error page?

What are best practices for this?

Thanks
John
0
Comment
Question by:iftech
  • 4
  • 3
  • 3
  • +2
14 Comments
 
LVL 21

Accepted Solution

by:
naspinski earned 500 total points
ID: 33749189
I just use ELMAH, it is simple to set up, free and open-source and all of this will be taken care of for you.

http://www.naspinski.net/post/Installing-ELMAH-for-simple-error-logging.aspx
http://code.google.com/p/elmah/
0
 

Author Comment

by:iftech
ID: 33780693
Thanks for the response.

I tried implementing ELMAH with very little success.

First: I get 404 error when I try: http://localhost:58730/elmah.axd

Second:  I have a www folder which is the root folder of the ASP.net. app In web.config I have
<customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/error.aspx" />
 so when I try: http://localhost:58730/www/elmah.axd
I get redirected to my default error page.  

Third: Nothing is being logged into the SQL server table Elmah_error.

Here are the parts of web.config:





See nay issues? thanks.

<configuration>
	<configSections>
    <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
			<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
				<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
				<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
					<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
					<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
					<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
					<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
				</sectionGroup>
			</sectionGroup>
		</sectionGroup>
    <!--ELMAH-->
    <sectionGroup name="elmah">
      <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
      <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
      <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
      <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
    </sectionGroup>
    <!--ELMAH-->
  </configSections>
  <!--ELMAH-->
  <elmah>
    <security allowRemoteAccess="yes" />
    <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="Data Source=testbox\testbox08;Initial Catalog=eDENT;User ID=xxx;Password=xxxx" />
  </elmah>
  <!--ELMAH-->

	<system.web>
		<!-- 
            Set compilation debug="true" to insert debugging 
            symbols into the compiled page. Because this 
            affects performance, set this value to true only 
            during development.
        -->
    <!--ASP.Net Security work around & ELMAH-->
    <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/error.aspx" />
    <!--ASP.Net Security work around-->

		<httpHandlers>
      <add  verb="*" path="*.jpg" type="Thumb.ThumbnailHandler" />
      <add  verb="*" path="*.jpeg" type="Thumb.ThumbnailHandler" />
      <add  verb="*" path="*.gif" type="Thumb.ThumbnailHandler" />
			<remove verb="*" path="*.asmx" />
			<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
			<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
			<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
      <!--ELMAH-->
      <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
      <!--ELMAH-->
    </httpHandlers>

		<httpModules>
			<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <!--ELMAH-->
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
      <!--ELMAH-->
		</httpModules>

Open in new window

0
 
LVL 15

Expert Comment

by:crisco96
ID: 33793673
So what I would do is set customErrors mode to RemoteOnly in the web.config (this will prevent the security vulnerability). Then in the Application_Error method in the global.asax do your error handling where you'll write to the database and possibly send an email.

Things that are useful to know in Application_Error:
1. You can access the exception that was thrown with System.Web.HttpContext.Current.Server.GetLastError()
2. You can access session variables with System.Web.HttpContext.Current.Session["VarName"]
3. You can access posted data with System.Web.HttpContext.Current.Request.Form["FieldName"]
4. As long as you don't do a response.redirect or response.end in Application_Error you will not be vulnerable to the asp.net vulnerability
0
 
LVL 21

Expert Comment

by:naspinski
ID: 33794466
Do you have the elmah dll in your bin or registered on your server?
0
 
LVL 21

Expert Comment

by:Craig Wagner
ID: 33794479
Setting customErrors to RemoteOnly is not the only thing you need to do to prevent the vulnerability. Unfortuantely crisco96's response leaves out a few rather important steps from what you need to do. As Phil Haack said in a recent blog post, "I’ve seen a lot of questions about [ScottGu’s] mitigations, as well as a lot of bad advice. The best advice I’ve seen is this - if you’re running an ASP.NET application, follow the advice in Scott’s blog to the letter. Better to assume your site is vulnerable than to second-guess the mitigation."

Here is a link to ScottGu's suggestions. Be sure to follow the link in this post to his first post you follow ALL the steps needed.

http://weblogs.asp.net/scottgu/archive/2010/09/24/update-on-asp-net-vulnerability.aspx

Back to your question...

Application_Error will fire if you have the using customErrors mode set to Off or RemoteOnly.

As long as you are using redirectMode="ResponseRewrite" on your customErrors tag, you will be able to access the exception that caused the problem from your error page using Server.GetLastError(). I believe you lose the Session variables though.

There isn't one and only one way to skin this cat. If you have information you need to get from Session or the Request you should get that information in Application_Error (it's the only place that information is available).

In one web site I've developed we have code in Application_Error that gathers everything we want to log from GetLastError and Session, writes to the log, and then allows the .NET framework (via customErrors) to redirect to the error page.

Another application I wrote I didn't need anything from Session, so rather than splitting the responsibilities between two different classes I decided to do all the logging in the error page.

One advantage of doing everything in the error page is that there are certain types of errors that won't trigger Application_Error because .NET doesn't ever forward the request to your code, it just immediately triggers an error condition. Requesting the WebResource.axd (as the vulnerability does) bypasses the Application_Error event altogether.
0
 
LVL 28

Expert Comment

by:strickdd
ID: 33795377
It looks to me like Craig simply reiterrated what Crisco said, but first said it's a bad thing and then said that's what he does himself. He also simply gave information on the recently announced security vulnerability which the OP obviously knows about.

The biggest keys are:
1) do not return different errors based on the error type (404 vs. 500)
2) application_Error will fire assuming the request hits your web app. Otherwise the IIS error handler will fire and show the ugly yellow and red error message, this is where the customerrors tag comes in.
3) Application_error will have acces to all server, error, form, and session variables through the HttpContext
4) Application_error can be used to send emails and store to a DB. Just make sure you don't have any errors in this code itself. Use try, catch, finally where appropriate.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:iftech
ID: 33799472
I'm a little confused now. Should I  use Application_Error to log errors  or work on getting ELMAH to work correctly to log errors?  Any one better than the other?

Thanks for the responses guys. Really appreciate it.
John
0
 
LVL 21

Expert Comment

by:Craig Wagner
ID: 33799641
@strickdd:

It appears you read about half of what I wrote before repeating most of ScottGu's advice and rewording what I stated. Your points, in order:

1. This can be obtained through the link to ScottGu's blog.
2. I stated this in my last paragraph.
3. This was stated by both crisco96 and myself.
4. This is equivalent to saying, "Anywhere you write code in your app can be used to send email..." Not exactly earth-shattering information in this point.

I did not simply reiterate what crisco96 said. I elaborated on it, stating that crisco96's advice was incomplete (he stated that all you have to do to avoid the vulnerability was add mode="RemoteOnly" to customErrors, which is not true). Rather than going into detail about what you are supposed to do, I simply pointed the OP to ScottGu's blog.

I also never said it was a bad thing. I answered one of the OP's direct questions ("will Application_Error fire even though I'm using <customErrors> in web.config") which no one had done until this point. I then pointed out the differences between using the two locations (Application_Error vs. error page). I provided information to help the OP make an informed decision about what was right for his environment, because there is no "right" or "wrong" answer to this question.

I respectfully request if you're going to criticize my comments, please take the time to fully read and comprehend them first.
0
 
LVL 21

Expert Comment

by:Craig Wagner
ID: 33799746
@iftech:

Define "better"?

ELMAH appears to give you more out-of-the-box functionality. It is code you don't have to maintain. If you have multiple applications it's a nice way to ensure they're all handled consistently.

On the other hand, if you write the handling code yourself you can control every aspect of what it does and make it do exactly what you want it to do. If you've only got one application and will never have any more perhaps the consistency isn't a big deal.

Unfortunately those are not questions we can answer for you. You have to look at your needs, your environment, your timeline and figure out for yourself what the best course of action is. There is almost never one right answer or silver bullet (http://en.wikipedia.org/wiki/No_Silver_Bullet) to a problem.
0
 

Author Comment

by:iftech
ID: 33800403
@naspinski:

I do have both Elmah.dll and Elmah.pdb in the bin folder. Did you notice anything with web.config that isn't right?
I think I got got all the steps.

1) Place Elmah.dll in bin folder.
2) run SQLServer.sql on the db I want to create ELMAH_Error table and stored procedures (the table and the three procedures are there)
3) edit web.config as I showed above

I decided to go with ELMAH because I several projects I need to do this for. However I do not want to do it at the server level.

Thanks
John
0
 
LVL 21

Expert Comment

by:naspinski
ID: 33802350
It all looks good to me.

Is this the newest version?  Maybe something has changed - have you checked with the documentation on the ELMAH site?
0
 

Author Comment

by:iftech
ID: 33803672
I downloaded it this week Monday to be exact, so I'm sure it's the newest version.
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Foreword (July, 2015) Since I first wrote this article, years ago, a great many more people have begun using the internet.  They are coming online from every part of the globe, learning, reading, shopping and spending money at an ever-increasing ra…
Boost your ability to deliver ambitious and competitive web apps by choosing the right JavaScript framework to best suit your project’s needs.
Viewers will get an overview of the benefits and risks of using Bitcoin to accept payments. What Bitcoin is: Legality: Risks: Benefits: Which businesses are best suited?: Other things you should know: How to get started:
This tutorial walks through the best practices in adding a local business to Google Maps including how to properly search for duplicates, marker placement, and inputing business details. Login to your Google Account, then search for "Google Mapmaker…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now