What is often overlooked as a source of potentially
harmful information about the internal implementation of a service are
exceptions or error messages. Services are sometimes designed to return
detailed data about the nature of a given exception, thereby
inadvertently disclosing information about their underlying architecture
that can be abused by malicious consumer programs.
Exception Shielding prescribes that exception information be sanitized
prior to being sent to consumers. The sanitization of exception data is
usually based on a process whereby some or all parts of the actual
exception information are removed or replaced with data considered safe.
Note
The Exception Shielding pattern is considered a security pattern. It is covered here as it
demonstrates a specialized application of the Service Abstraction principle.
In WCF there is a
configuration setting that will make WCF replace all exceptions with a
generic SOAP fault message, thereby not revealing anything unwanted to
service consumers.
Here’s the statement that needs to be configured:
Example 1.
<serviceDebug includeExceptionDetailInFaults="False" />
|
Another alternative
is to remove this configuration line altogether as the default behavior
of WCF is to not include exception details in fault messages. This will
still return a SOAP fault, but it will not be useful to consumers.
Here is how this type of fault message will look:
Example 2.
<s:Fault xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <faultcode xmlns:a="http://schemas.microsoft.com/ net/2005/12/windowscommunicationfoundation/dispatcher"> a:InternalServiceFault </faultcode> <faultstring xml:lang="en-US"> The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug>configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs. </faultstring> </s:Fault>
|
You may actually want to
provide more information in faults and even return different faults in
different situations (for example when encountering a “Quota” error when
a consumer has used the service more than the service’s SLA allows or a
“Temporarily Unavailable” error when some of the service’s essential
resources are offline).
Note also that the original
exception produced by the service logic may contain information that is
important for systems maintenance or customer support and therefore may
need to be logged. For these types of situations, the sanitized fault
message content can still include a unique ID that can be sent to the
customer in order to allow for the correlation of the exception with the
logged details.
In WCF, this type of behavior is built-in, in that all logs created within an activity (a service call) will have the same ActivityId. You can make sure that this ActivityId is propagated to composed services so that all logs in a service composition can be found using the same ActivityId.
To propagate the ActivityId
to other WCF services and clients, you will need to add some
configuration details because even when the propagateActivity attribute
value is set to “true,” you may find that the ActivityId is still not propagated.
This is because you still need to configure a listener, as shown here:
Example 3.
<system.diagnostics> <sources> <source name="System.ServiceModel" propagateActivity="true"> <listeners> <add name="defaultListener" type="System.Diagnostics.DefaultTraceListener" /> </listeners> </source> </sources> </system.diagnostics>
|
These
configuration settings need to be made on both ends of a message
exchange (service and consumer). WCF passes the ActivityId around in a
message header that is also added to fault messages.