Gaurav’s Monologue

on Software Architecture, .NET Framework and Connected System Technology

Archive for the ‘Security’ Category

Message Authentication Failure : TimeStamp & Clock Skew Issue (Part 2)

Posted by intrepiddeveloper on August 25, 2008

When using Message level security with UserName credential in some WCF bindings, you might get into a situation where you start getting Message Authentication Failure(See my earlier post for more details) .

The reason for this is due to the fact that WCF frameworks implementation of WS-Security by default enables Message Replay Detection. Message replay is an attack where a message is presented to a processor more than once in the hopes of fooling the processor into taking some action. One protection against message replay and other timing-based attacks is to have the sender timestamp messages. Security timestamps are only valid for a limited window of time, typically represented by a creation time and an expiration time. The processor may declare that messages have a limited lifetime, which can be checked by using the security timestamp.

The sender and receiver have to agree on what time means. Since the two sides don’t share a common clock, they need to each have a clock and those clocks need to agree on the current time to a certain precision. It’s impossible to make two clocks exactly agree and there’s some threshold after which you have to assume that the clocks are measuring two different times. The difference between the clocks is called the skew and the threshold is called the maximum allowed clock skew.
When checking creation and expiration times, the maximum clock skew becomes a factor because it determines whether two times might be the same. Here are the interesting checks for a security timestamp.

  • If the creation time is after the local time plus the maximum clock skew, then the creation date is actually in the future.
  • If the expiration time is before the local time minus the maximum clock skew, then the expiration date is actually in the past.
  • If the creation time is before the local time minus the maximum clock skew and minus the message lifetime, then the message is too old and may be part of a replay attack.

This clock skew is a configurable setting on the SecurityBindingElement through the local client settings or local service settings. Changing that value changes the tolerance for comparing times. The default clock skew value is 00:05:00.

Keep in mind that this message timestamp value is checked both ways i.e. from the client to the Service(checked at the service side) AND from the Service to the client (check on the client side).

There are two solutions to this:

  1. Make sure both the server and client clocks are synced with a standard time server. This approach may not be applicable when you don’t have control over the server or the client machines.
  2. Change the default values from the Service configuration by defining a custom binding. An example as as below.

<binding name="CustomDevWSHttpBinding">
  <security authenticationMode=“UserNameOverTransport“ requireSecurityContextCancellation=“true“>
    <localservicesettings maxClockSkew=“00:10:00“ />
    <localclientsettings maxClockSkew=“00:10:00“ />
    <secureconversationbootstrap />
  </security>
  <textmessageencoding />
  <httpstransport />
</binding>

Note: For some reason, when I generate the client proxy’s configuration using SvcUtil, the clients ClockSkew value still default to 00:05:00 but you can manually change that to a suitable value.

Recently came to find out that the settings I mentioned above are going to be local to the service and the domain it operates in, hence the ClockSkew can be set on the service side to a suiable value or to turn it off set the maxClockSkew=Infinite.However the generated Client configuration will always default to 5 mins and will have to be changed manually if required.

Posted in Security, WCF | Leave a Comment »

Message Authentication Failure : TimeStamp & Clock Skew Issue (Part 1)

Posted by intrepiddeveloper on August 24, 2008

Recently I came across an interesting issue with service binding and message security in WCF. The service was hosted in IIS and used message level security with UserName Credential and https for transport security. The two exposed bindings are as follows:

<wshttpbinding>
  <binding name="wsHttpWithMessageSecurity">
    <security mode ="TransportWithMessageCredential">
      <message clientCredentialType="UserName" negotiateServiceCredential="true"/>
    </security>
  </binding>
</wshttpbinding>

<basichttpbinding>
  <binding name="MyBasicHttpBinding">
    <security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm =""/>
      <message clientCredentialType ="UserName"/>
    </security>
  </binding>
</basichttpbinding>

Everything worked fine when I testing my client and service hosted on the same machine i.e. local IIS but when I deployed the service to a remote server (IIS6/Win2K3 server) the service started throwing “Error verifying security of the message” exceptions/faults. I made sure there where no server/client certificate or SSL issues but that did not seem to be the issue.

Here is the stack trace of the exception caught on the client side:

System.ServiceModel.Security.MessageSecurityException was caught
Message=”An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.”
Source=”mscorlib”
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.ProcessReply(Message reply, SecurityProtocolCorrelationState correlationState, TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

InnerException: System.ServiceModel.FaultException
Message=”An error occurred when verifying security for the message.”

I enabled Security Auditing on the service for MessageAuthenticationAuditLevel =”Failure” and retested the client and checked the auditing log on the server. The log had the following entry:

Message authentication failed.

Service: https://mytestserver.com/service.svc/endpoint01

Action: http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT

ClientIdentity:

ActivityId: 00000000-0000-0000-8f01-0060000000a2

MessageSecurityException: The security timestamp is stale because its expiration time (‘2008-08-04T20:29:58.924Z’) is in the past. Current time is ‘2008-08-04T20:45:18.828Z’ and allowed clock skew is ‘00:05:00

Basically the  client message failed message authentication since it is outside the acceptable time range when processed by the service. The main reason for this being the server & client clocks out of sync or mismatched.

In the next post (i.e Part 2) I will explain the reason and the work around for this issue.

Posted in .NET, Security, Technology, WCF | Leave a Comment »

Security Event Logging & Auditing

Posted by intrepiddeveloper on August 7, 2008

Few days ago I was trying to debug a WCF service hosted on a remote server which was giving a very generic boilerplate security exceptions/faults. After scratching my head for sometime I decided to figure out how to enable logging these security exceptions on the server. I think for debugging purposes this is a great tool and should be the first step when hunting down an elusive bug.

Its actually pretty straight forward to enable Security event auditing in WCF. You simply need to enable this in the configuration of the service.

<configuration>
    <system .serviceModel>
      <behaviors>
        <behavior>
          <servicesecurityaudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />
        </behavior>
      </behaviors>
    </system>
  </configuration>

auditLogLocation‘ specifies which log to write to with possible values Default, Application and Security.

messageAuthenticationAuditLevel‘  & ‘serviceAuthorizationAuditLevel‘ indicated when to log the event i.e. on None ,Failure ,Success and SuccessOrFailure for message and service authorization respectively.

suppressAuditFailure‘ basically defines who (i.e. the service or the system) handles a AuditFailure event (like unable to write to log or log is full, etc). In case of true Audit Failures are ignored and request is processed normally.

In the Event Viewer note the source is listed as ServiceModel and message related information is logged in an un-encrypted form.

Posted in .NET, Security, Technology, WCF | Leave a Comment »

Generating Service Client Proxy

Posted by intrepiddeveloper on July 17, 2008

To consume a service you generally need a client side proxy of the service being consumed to talk to your application. Most of the time the simpler approach is to add a reference to the service in VisualStudio and let it work its magic. Eventually there will be situations where this approach is not sufficient and need more manual intervention. SvcUtil.exe (ServiceModel Metadata Utility) is a command line tool which comes as a part of the .NET Framework and does this job. In fact VisualStudio itself use this utility behind the scenes with all the right switches.

There are usually two steps involved with creating the client proxy, namely Get the Service metadata and Generate code from the metadata.

There might be two scenarios you might encounter when dealing with external Services, i.e.

1.      Hosted or Running Services. (should expose a MEX endpoint)

2.      Service assembly or library.

To generate client proxy and configuration from a compiled service assembly required two steps:

1.      Extract the service metadata as:

SvcUtil.exe /t:metadata serviceassemblyname.dll

This step would produce the WSDL and the XSDs from the assembly.

2.      Generate proxy from the metadata as:

SvcUtil.exe /t:code [path]*.wsdl [path]*.xsd /out:[path]Proxy.cs /config:[path]App.config

Now in case of a hosted/running service both steps 1 & 2 are usually combined as one as below:

SvcUtil.exe /t:code [Service URL] /out:[path]Proxy.cs /config:[path]App.config

I ran into an interesting problem when I tried to execute the above command against an IIS hosted service which exposes the MEX binding over https. ScvUtil failed to pull the service metadata and threw a “WS-Metadata Exchange Error. Could not establish trust relationship for SSL/TLS secure channel. The remote certificate is invalid according to the validation procedure.”

Now I know this is cause of the fact that the server certificate is not signed by a TrustedRootCA or installed in the trusted store. This is not unusual for development and test environments.

One option is to install the server certificate in the trusted store but I am trying to find if there is an option to override the validation procedure that the underlying protocols use to establish a secure channel. I know VisualStudio gives a warning in this case but you can still proceed if you choose to. I don’t know if there is way around with just using SvcUtil directly from command line, however for your Client side there is a work around explained below.

When a client applications trys to connect to a URI, it requests a System.Net.ServicePoint class instance through System.Net.ServicePointManager class. Each ServicePoint maintains its connection to the URI for specific time and then recycles. The ServicePointManager class has callback property (which is our hook-in point): public static RemoteCertificateValidationCallback ServerCertificateValidationCallback { get; set; } which basically verifys the remote SSL certificate used for authentication.

The sample below demonstrates how.

public class CustomCertificateValidation
    {
        CustomCertificateValidation()
        {
            System.Net.ServicePointManager.ServerCertificateValidationCallback +=
            new System.Net.Security.RemoteCertificateValidationCallback(CertValidate);
        }
        bool CertValidate(object sender,
        System.Security.Cryptography.X509Certificates.X509Certificate cert,
        System.Security.Cryptography.X509Certificates.X509Certificate.X509Chain chain,
        System.Net.Security.SslPolicyErrors error)
        {
            //Put your validation logic here
        }
    }

Posted in .NET, Security, Technology, WCF | Leave a Comment »