Securely Implement ELMAH For Plug And Play Error Logging

asp.net 0 comments suggest edit

ELMAH, which stands for Error Logging Modules and Handlers for ASP.NET, is an open source project which makes it easy to log and view unhandled exceptions via its pluggable architecture.

elmah

Having been around a while, a lot has already been written on it so I won’t rehash all that information. For more details, you can read the following:

All you need to know for the purposes of this post is that ELMAH is implemented as two key components:

  • An HTTP Module Used To Log Exceptions
  • An HTTP Handler for viewing Exceptions

In the sample web.config file that is included with the ELMAH download, the HTTP handler is configured like so:

<httpHandlers>
  <add verb="POST,GET,HEAD" path="elmah.axd" 
    type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>

This allows you to view the error log from the URL http://your-site/elmah.axd. There’s one big problem with this…you do not want to deploy this to your production site.

This would allow any joker with a browser to view your exceptions and potentially gain information that would allow someone to hack your site.

Personally, I think that the sample web.config should have elmah.axd be secured by default. It’s quite easy to do. Here’s what I did:

First, I changed the HttpHandler section to look like this:

<httpHandlers>
  <add verb="POST,GET,HEAD" path="/admin/elmah.axd" 
    type="Elmah.ErrorLogPageFactory, Elmah" />
</httpHandlers>

Notice that all I did was add admin to the path attribute.

I then added the following location element to my web.config.

<!-- Deny unauthenticated users to see the elmah.axd -->
<location path="admin">
  <system.web>
    <authorization>
      <deny users="?"/>
    </authorization>
  </system.web>
</location>

IMPORTANT: It’s important to note that I’m securing everything in the admin directory and that I’m making sure that elmah.axd is served from the root /admin URL. If the httpHandler “path” element was just “admin/elmah.axd” or “elmah.axd” I could inadverdently expose Elmah information.

Troy Hunt has a great write-up of the perils of getting ELMAH configuration wrong. In his post he shows a more robust way to secure elmah.axd. Put the httpHandlers section within the location section.

<location path="elmah.axd">
  <system.web>
    <httpHandlers>
      <add verb="POST,GET,HEAD" path="elmah.axd" 
        type="Elmah.ErrorLogPageFactory, Elmah" />
    </httpHandlers>
    <authorization>
      <allow roles="Admin" />
      <deny users="*" />
    </authorization>
  </system.web>
  <system.webServer>
    <handlers>
      <add name="Elmah" path="elmah.axd" verb="POST,GET,HEAD"
        type="Elmah.ErrorLogPageFactory, Elmah"
        preCondition="integratedMode" />
    </handlers>
  </system.webServer>
</location>

To demonstrate this in action, I’ve created a solution containing a Web Application project with ELMAH and authentication fully implemented.

The point of this sample app is to demonstrate how to set this all up. So for example, the login page has a button to auto-log you in. In the real world, you’d probably use a real login form. You can also change the authentication from Forms authentication to Windows authentication depending on your needs. That might make sense in many scenarios.

The app demonstrates in principle how to setup and secure the elmah.axd page. If you have SQL Express installed, you should be able to compile and run the demo without any extra steps to see ELMAH in action.

[Download the demo]

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

33 responses

  1. Avatar for Eric
    Eric July 24th, 2007

    Hi Phil, thanks for the sample.
    I just want to remind that you need to copy elmah.dll to the bin folder so that your demo works

  2. Avatar for Ryan Smith
    Ryan Smith July 24th, 2007

    That looks like a nice plug-in. I have just been sending all my website errors to me in emails VIA the application_onerror handler.
    I'll have to give this a try.

  3. Avatar for Haacked
    Haacked July 24th, 2007

    @Eric - I mentioned that you need to compile the app first. That will copy the Elmah dll into the bin folder.

  4. Avatar for Member Blogs
    Member Blogs July 24th, 2007

    .NET Example: Inheritance vs Object Composition IP Address Validation .net 2.0 Snippet Waiting for a

  5. Avatar for Ivan Porto Carrero
    Ivan Porto Carrero July 24th, 2007

    What's wrong with asp.net 2.0 health monitoring ?
    I used ELMAH in the past but am now going with health monitoring or NLog.
    I found Elmah to be ok but it didn't let me do all that i wanted it to do.

  6. Avatar for Haacked
    Haacked July 24th, 2007

    @Ivan - Take a look at the steps to setup health monitoring. I'll patiently wait here while you read through all of that.
    What's missing with Health Monitoring? Where's the UI to get at the events?
    There's nothing wrong with health monitoring, but I see it as instrumentation. It's great when you have the time to spend creating and raising various health events in your code.
    ELMAH serves a different purpose in my view. It's meant to be a quick pluggable way to log unhandled exceptions. It's not about instrumentation (though I think it can be used that way if you want).
    With just a little configuration, and in most cases without any code changes, ELMAH not only handles the capture and logging of unhandled exceptions but also provides a nice UI for viewing exceptions. It's great when you need to quickly add exception logging to an existing app.
    It doesn't necessarily replace Log4Net, NLog, Health Monitoring logging, but can be a complement.

  7. Avatar for Atif Aziz
    Atif Aziz July 24th, 2007

    @Haacked - Couldn't have positioned ELMAH better. It's definitely not a general-purpose logging framework nor one for instrumentation. It only logs unhandled exceptions in a non-invasive way (speaking code-wise). I usually discourage people from using it to log errors in their catch blocks because that purpose is served better by existing tracing facilities and frameworks and often by acutally handling the offending case gracefully in code.
    @Ivan - Also bear in mind that ELMAH was originally written for ASP.NET 1.1, but I think you already knew that. The new beta runs all the way across the board down to 1.0. That alone can help many of us who have to keep old ASP.NET applications humming in production yet cannot afford to touch the code base anymore.
    ELMAH targets as much operators and administrators in data centers as it does developers. This is reason it was designed to be pluggable, requiring (hopefully) absolutely no changes to the code base. It by no means competes with health monitoring, which became only available with ASP.NET 2.0. If you're happy with that solution, I'd stick to it. In general, however, I've seen people add ELMAH as an after-thought to an application in production because they needed more information than what their users would be telling them (which usually went along the lines of, "...and the page just broke with some odd error and then I just closed the browser"). The first reaction then is to get something up and running quickly and that's where ELMAH has been coming in. You get logging of uncaught exceptions plus viewing in 5 to 10 minutes. It's a rather small and proactive step towards speeding up your reactive support. :) As a longer-term solution, the application and development and support teams should definitely look into health monitoring.
    I still continue to use ELMAH because I get web pages and RSS feeds for free in addition to logging using a rather modest configuration footprint. A very large and complex project may warrant more time investment into health monitoring, but by then you may not necessarily be the person looking into that piece. The other more subtle reason is that ELMAH is now open source. This means that it can be enhanced by the community to support cases and scenarios that you just can't always afford to sit and wait for Microsoft to provide or fix. Sometimes, you just have roll up your sleeves and at that point ELMAH can serve as a good starting point. For example, if health monitoring does not have any UI then why not just wrap an ErrorLog implementation around the aspnet_WebEvent_Events table? That way you can leverage ELMAH pages and feeds while using health monitoring for the actual logging. Both can complement each other. How smoothly this can be done has to be investigated. If anyone wants to look into that, I'm sure it'd be a broadly welcomed addition. I actually started looking into it myself when I was seeing where ELMAH could leverage ASP.NET 2.0 futher than what was available earlier. Unfortunately, it had to go on the back burner as I had to focus on getting ELMAH setup as an open source project after GDN decided to shutdown.

  8. Avatar for Sameer
    Sameer July 24th, 2007

    Very nice.. Exactly what I was looking for and we are this week just discussing how to handle exceptions and I was given the task to find a solution and I found this on your site!

  9. Avatar for Joe
    Joe July 24th, 2007

    We're using a similar (although home grown) technique on my current project, but expose the errors as a (locked down) rss feed that all the developers subscribe to. This has the benefit of letting us know pretty quickly if bad code makes it past our tests and actually gets into production.

  10. Avatar for Eric
    Eric July 26th, 2007

    @Ivan Porto Carrero
    I have put an example on the ELMAH dissusion group how you could use the health monitoring feature in combination with ELMAH. All the (configured) events are rerouted to ELMAH.
    Look at:
    http://groups.google.com/gr...
    Please take your time to give some feedback in the group.
    Thanks
    Eric

  11. Avatar for jawrat
    jawrat August 14th, 2007

    YES! Thank you for the simple explanation. we've been using elmah for awhile and the devs insisted that there was no way to secure it. needless to say I was not happy about having it up on production unsecured. Now it's secured and I can go back to being paranoid about other things...
    ;)

  12. Avatar for Scott
    Scott September 21st, 2007

    So do I need to create a directory within the website called "Admin" or you just saying that in the webconfig? You didn't explain that very well or I'm one of the slower kids in the class and need further explaining.
    P.S. I love this tool! AWSOME

  13. Avatar for Haacked
    Haacked September 24th, 2007

    Scott, you don't need to create a physical directory named "Admin".
    The HttpHandler will look for requests to "/admin/elmah.axd" and handle those requests.
    Keep in mind that elmah.axd doesn't physically exist either. The handler declaration indicates that the class Elmah.ErrorLogPageFactory implements IHttpHandler and will thus handle those requests.

  14. Avatar for Rick
    Rick November 23rd, 2007

    The demo works for me, but when I try to add it to my application, I'm having a problem. When I try to display /admin/elmah.axd, I get an System.Web.HttpException. This error is written to the SQL database, so the logging part is working. The error is "Path '/<my app>/admin/elmah.axd' was not found." I presume it is something in web.config, but I can't see what. I copied and pasted from the demo the sections 'configSections' and 'elmah' into the main body of the 'configuration' section, 'httpModules' and 'httpHandlers' in to the 'system.web' section, and the 'location' section containing the 'admin' restriction into the end of the 'configuration' section.
    I'm at the stage of understanding this where I could make a pretty simple mistake and not know why, so hints are appreciated.

  15. Avatar for Rick
    Rick November 23rd, 2007

    OK, I made it work.
    In the demo program, the handler references 'path="/admin/elmah.axd"'. For this to work in my application, it has to be 'path="admin/elmah.axd"' (i.e. no leading slash).
    I don't understand why one program uses the leading slash and the other does not.

  16. Avatar for Haacked
    Haacked November 23rd, 2007

    Glad you got it working. Thanks for posting an update with the fix.

  17. Avatar for Philip Lippard
    Philip Lippard December 5th, 2007

    Great demo project. I have been using ELMAH for quite some while...and I agree that ASP.NET V2 Health monitoring and ELMAH are NOT mutually exclusive. I use both with much success.

  18. Avatar for Philip Lippard
    Philip Lippard December 5th, 2007

    Prior to reading this blog post I had been using ELMAH, however had not secured ELMAH....now I am. However, I found that I had to secure ELMAH by specifying the following...
    <location path="ELMAH">
    <system.web>
    <authorization>
    <allow roles="Admin"/>
    <deny users="*"/>
    </authorization>
    </system.web>
    </location>

    I expected the following specification to also work, however it would NOT work...
    <location path="ELMAH/ErrorLog.axd">
    <system.web>
    <authorization>
    <allow roles="Admin"/>
    <deny users="*"/>
    </authorization>
    </system.web>
    </location>

    In both cases my Http Handler specifications were specified as follows...
    <httpHandlers>
    <add verb="POST,GET,HEAD"
    path="ELMAH/ErrorLog.axd"
    type="GotDotNet.Elmah.ErrorLogPageFactory, GotDotNet.Elmah, Version=2.0.50727.42, Culture=neutral, PublicKeyToken=89e7ba9b9c08cfca"
    </httpHandlers>
    Any thoughts you may have on why the path="ELMAH/ErrorLog.axd" is NOT working is appreciated.
    Cheers...

  19. Avatar for C# articles and tutorials on S
    C# articles and tutorials on S December 22nd, 2007

    Using time to your advantage in order to achieve great results at your place of employment. This tip has been used successfully several times by me to implement remarkable changes in our process with full approval of management!

  20. Avatar for Gersy
    Gersy March 15th, 2008

    Hello, this is great, but I can't run this example in vs2005 , I'm new in this so any help, or small sample ?? thanks a lot anyway
    plz reply to this moudgersy@gmail.com

  21. Avatar for Brent Lamborn
    Brent Lamborn June 1st, 2008

    Elmah rocks. I just discovered it. I can't believe I have never heard of it until about a week ago. Thanks.

  22. Avatar for Steve
    Steve January 18th, 2010

    The demo's zip file appears to be corrupt. Hopefully a good copy can be made available, or possibly an update to this using MVC?

  23. Avatar for Phil Haselden
    Phil Haselden February 16th, 2010

    If you remove the leading slash from your path you might find people are able to bypass your security by using a path such as http://<site>/xxxx/admin/elmah.axd.
    Check out the question and answer from Alan to this question: stackoverflow.com/....
    I think this would address Philip Lippard's issue too.
    For my site I did this:

    <location path="admin">
    <system.web>
    <httpHandlers>
    <add path="elmah.axd" verb="POST,GET,HEAD" type="Elmah.ErrorLogPageFactory, Elmah"/>
    </httpHandlers>
    <authorization>
    <allow roles="Administrator"/>
    <deny users="*"/>
    </authorization>
    </system.web>
    </location>

  24. Avatar for Paulo Aceves
    Paulo Aceves May 5th, 2010

    What about MVC
    some example???

  25. Avatar for Rick
    Rick October 31st, 2010

    @Hacked - Really worthful, I have a problem while imlement Elmah, I have gone through this post and discussion and I got the solution.
    You wrote in above how to get a folder specific Elmah.axd file denying all anonymous users.
    But, my question is what about those who are not using form authentication and just using Custom-Authentication, Authenticate site visitors by Sessions etc. By allowing all registered members mean to invite any one who is registered with site.
    I am sure, you already have the solution for this.
    One more thing apart from Error Logging - I need to implement Routing or Url-Rewritting in my asp.net 3.5 / asp.net 4.0 application. Is there any such tool like Elmah?

  26. Avatar for Kevin
    Kevin November 17th, 2010

    As an alternative, changing the web.config entry entry from
    <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah"/>:
    to:
    <add verb="POST,GET,HEAD" path="secretFolderName/elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah"/>
    should help. Doing that, someone would have to guess the "secretFolderName" in order to access elmah.

  27. Avatar for Tariq Ahmed
    Tariq Ahmed December 25th, 2010

    The demo zip file seems to be corrupt. Can i have the correct url or file?
    Thanks.

  28. Avatar for Jed
    Jed August 23rd, 2011

    It appears the demo zip file has been updated; Anyone still looking for the original can find it at:
    web.archive.org/.../Elmah-Demo.zip

  29. Avatar for haacked
    haacked September 18th, 2011

    I fixed the download link on this post.

  30. Avatar for mandeepsingh
    mandeepsingh May 8th, 2012

    It appears the demo zip file has been updated; Anyone still looking for the original can find it at

  31. Avatar for Optimus Most Prime
    Optimus Most Prime September 11th, 2013

    I would like to point out that code changes are SOMETIMES required to make ELMAH work. For example, the GlobalErrorHandler class was not logging my exceptions in ELMAH. I had to explicitly write one line of code in my GlobalErrorHandler.cs to make it work:

    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);

  32. Avatar for Preguntón Cojonero Cabrón
    Preguntón Cojonero Cabrón June 25th, 2016
  33. Avatar for test user
    test user November 23rd, 2016

    sample download not working