Shielding Exceptions at WCF Service Boundaries

In Windows Communication Foundation (WCF), to prevent details of the service implementation from escaping the secure boundary of the service, unknown exceptions should not be sent to the client application. This is controlled through the includeExceptionDetailInFaults attribute in the <serviceDebug> element in the WCF configuration. To enable exception shielding, this attribute must be set to false. If not specified in the configuration file, this property is set to false.

Note

The includeExceptionDetailInFaults configuration setting is used only for unknown or unhandled exceptions. It does not have any effect on known exceptions, where the operation has a FaultContract with the known fault type and the operation throws a FaultException<knownFault> where knownFault is in the fault contract.

Exception shielding helps prevent a Web service from disclosing information about the internal implementation of the service when an exception occurs. The following forces explain why you should use exception shielding:

  • Exception details may contain clues that an attacker can use to exploit resources used by the system.
  • Information related to anticipated exceptions needs to be returned to the client application.
  • Exceptions that occur within a Web service should be logged to support troubleshooting.

Only exceptions that have been sanitized or are safe by design should be returned to the client application. Exceptions that are safe by design do not contain sensitive information in the exception message and they do not contain a detailed stack trace, either of which might reveal sensitive information about the Web service's inner workings. You should use the Exception Shielding pattern to sanitize unsafe exceptions by replacing them with exceptions that are safe by design.

The Exception Handling Application Block includes support for exception shielding at WCF service boundaries. This support consists of the following:

  • The Exception Shielding Attribute, which is used to associate a named exception handing policy configured in the Exception Handling Application Block with a WCF service operation. For more information, see the following section Using the Exception Shielding Attribute.
  • The Fault Contract Exception Handler, which converts an exception to a specific type of Fault Contract and maps the desired properties of the exception to the Fault Contract. For more information, see the following section Using the Fault Contract Exception Handler.

Using the Exception Shielding Attribute

To enable the exception shielding feature in an WCF service

  1. Add references to the following assemblies:
    • Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.dll
    • Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF.dll
    • Microsoft.Practices.EnterpriseLibrary.Common.dll
    • Microsoft.Practices.Unity.dll
    • Microsoft.Practices.Unity.Interception.dll
    • Microsoft.Practices.ServiceLocation.dll
  2. Add a using (C#) or Imports (Visual Basic) statement to import the namespace Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.WCF
  3. Add the ExceptionShielding attribute to a service implementation class or service contract interface, and specify the name of the exception policy to use as a constructor parameter. If you do not specify the name of a policy in the constructor parameter, or if the specified policy is not defined in configuration, the shielding implementation always looks for a policy named "WCF Exception Shielding".
  4. Add the Exception Handling Application Block configuration sections to the service's Web.config file, and then define the desired exception policies and handlers. The Fault Contract exception handler is used to map exceptions to fault contracts that are defined on the operation contract. This exception handler is described in the following section.
  5. Implement exception handling logic in your service's client applications to catch the service's possible exceptions and send them to the Exception Handling Block.

The following code shows a service contract that specifies the fault contract named SystemUnavailableFault that may be returned by the GetQuote operation. The ExceptionShielding attribute applied to a service implementation class (in this case the QuoteService class), specifies that WCF should execute the exception handling policy named QuoteServicePolicy when an exception occurs.

[ServiceContract]
public interface IQuoteService
{
  [OperationContract]
  [FaultContract(typeof(FaultContracts.SystemUnavailableFault))]
  QuoteResponseType GetQuote(QuoteRequestType request);
}

[ExceptionShielding("QuoteServicePolicy")]
public class QuoteService : IQuoteService
{
  public QuoteResponseType GetQuote(QuoteRequestType request)
  {
    // Method code here...
  }
}
'Usage
<ServiceContract> _
Public Interface IQuoteService

  <OperationContract> _
  <FaultContract(GetType(FaultContracts.SystemUnavailableFault))> _
  Function GetQuote(request  As QuoteRequestType) As QuoteResponseType

End Interface

<ExceptionShielding("QuoteServicePolicy")> _
Public Class QuoteService
  Implements IQuoteService

  Public Function GetQuote(request  As QuoteRequestType) As QuoteResponseType _
    Implements IQuoteService.GetQuote
      ' Method code here...
  End Function

End Class

Using the Fault Contract Exception Handler

When using the Exception Handling Application Block for exception shielding in WCF applications, you can use the Fault Contract exception handler to convert a run time exception to an appropriate Fault Contract type. This exception handler also enables you to map properties from the original exception and the Handling Instance ID to properties in the Fault Contract.

To use the Fault Contract exception handler

  1. Create an exception handling policy that includes the appropriate exception types for your application. For more information, see Entering Configuration Information.
  2. Configure the exception type, specifying the post-handling action as ThrowNewException. This means that the block throws the new exception that has been created by wrapping the original exception. The throw occurs after the entire chain of handlers runs.
  3. Add a new Fault Contract exception handler for the specified exception types.
  4. Configure the Fault Contract exception handler:
    • Specify the desired Fault Contract Type that should be returned to the client.
    • Add the exception message to be used in the Fault Contract returned to the client.
    • Optionally, configure how properties from the original exception will be mapped to the Fault Contract. Add a mapping for each property you want to map in the Property Mappings section of the handler configuration. The Name property of a mapping refers to a property name on the Fault Contract. The Source property of a mapping specifies the name of the property on the original exception from which the value should be retrieved. You can also specify a Source value of {HandlingInstanceId} to add the current handling instance ID to a Fault Contract property.

The Fault Contract Exception handler will automatically map any properties from the exception to the Fault Contract if their names match and their types are compatible. If you want to prevent this, you can add a mapping with a Name of the Fault Contract property name and a Source with an empty string.