.NET 2.0 Security Guidelines - Exception Management

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Chaitanya Bijwe


Contents

Use structured exception handling

Use structured exception handling instead of returning error codes from methods because it is easy to forget to check a return code, and, as a result, your code will fail to an insecure mode.


Microsoft Visual C# ® development tool and Microsoft Visual Basic® .NET development system provide structured exception handling constructs. C# provides the try / catch and finally construct. You can protect code by placing it inside try blocks, and implement catch blocks to log and process exceptions. Also, use the finally construct to ensure that critical system resources such as connections are closed, whether an exception condition occurs or not.


Do not log sensitive data

Avoid logging sensitive or private data such as user passwords. Also, make sure that exception details are not allowed to propagate beyond the application boundary to the client. The rich exception details included in Exception objects are valuable to developers and attackers alike. Log details by writing them in the event log to aid problem diagnosis.


Do not reveal system or sensitive application information

Do not reveal too much information to the caller. Exception details can include operating system and .NET Framework version numbers, method names, computer names, SQL command statements, connection strings, and other details that are very useful to attackers. Write detailed error messages in the event log, and return generic error messages to the user.


Consider exception filter issues

If your code fails to catch exceptions and your code uses impersonation, a malicious user could use exception filters to execute code that runs under the impersonated security context, even if you are reverting the impersonation in your finally block. This is particularly serious if your code impersonates a privileged account. If your code does not catch the exception, exception filters higher in the call stack can be executed before code in your finally block is executed.


If you use programmatic impersonation, use structured exception handling and put the impersonation code inside try blocks. Use a catch block to handle exceptions and to prevent exceptions propagating. Use a finally block to ensure that the impersonation is reverted, as shown in the following example.

 using System.Security.Principal;
 . . .
 WindowsIdentity winIdentity = new WindowsIdentity("username@domainName");
 WindowsImpersonationContext ctx = null;
 try
 {

  ctx = winIdentity.Impersonate();
  // Do work.
  ...
 }
 // Do not let the exception propagate. Catch it here.
 catch(Exception ex)
 {
  ...
 }
 finally
 {
  // Stop impersonating.
  ctx.Undo();
 }


By using a finally block, you make ensure that the impersonation token is removed from the current thread, even if an exception is generated. By preventing the exception from propagating from the catch block, you make sure that exception filter code higher in the call stack does not execute while the thread still has an impersonation token attatched to it.


Note Exception filters are supported by Microsoft Intermediate Language (MSIL) and Visual Basic .NET.


Consider using an exception management system

Consider using a formal exception management system for your application because this can help improve system supportability and maintainability and ensure that you detect, log, and process exceptions in a consistent manner.


For information about how to create an exception management framework and about best practices for exception management in .NET applications, see:


Fail early to avoid unnecessary processing that consumes resources

Check that your code fails early to avoid unnecessary processing that consumes resources. If your code does fail, check that the resulting error does not allow a user to bypass security checks to run privileged code.

Personal tools