Export (0) Print
Expand All

Secure Hosting and Deployment of WCF Services

 

Secure Hosting and Deployment of WCF Services

Girish Phadke
Tata Consultancy Services Ltd.

August 20, 2007

Summary: Girish Phadke in this paper explains the various steps in involved in securely hosting and deploying a WCF service.  He starts with a discussion on the various criteria used to select an appropriate WCF service host, service bindings and the options available for choosing and provisioning a WCF service account. He examines the merits and demerits of using impersonation in a WCF service along with the different mechanisms available to implement it. He goes on to discuss the common attack vectors in a WCF service and finally examines the provisioning that is required on the infrastructure resources such as File System, MSMQ, Event Log etc. to enable a WCF service to run successfully.  (28 printed pages)

Before a WCF service can be deployed in a production environment, typically there are a number of decisions that need to be made. Such decisions range from selecting an appropriate host for the WCF service, selecting a binding for the WCF service, selecting and provisioning a service account, securing the service against the various attack vectors to provisioning the requisite infrastructure resources for the WCF service. 

Selecting a Service Host

WCF Service has to be hosted in a Service Host before it can be deployed and used. A Service Host typically provides the execution environment for the WCF service code. Different Service hosts provide a range of features for service deployment such as:

·         Enabling a WCF Service to be exposed to the clients over various wire protocols such as HTTP, HTTPS, TCP, MSMQ, Named Pipe etc.

·         Providing a security context for the execution of the WCF Service

·         Providing on-demand message based activation of the WCF Service

·         Providing a mechanism to configure the WCF Service

·         Providing a mechanism to monitor the statistics and health of the WCF service

·         Providing rapid fail protection

·         Providing process management features such as IdleTimeout, Shutdown  and StartupTimelimit

·         Providing the necessary tools for WCF Service Management

A WCF service can be hosted in the following types of hosts:

Managed Application / Self Host

A .NET managed application can host a WCF service by creating an instance of ServiceHost class. ServiceHost class is part of the System.ServiceModel namespace. Hosting a WCF Service in a managed application is also sometimes referred to as Self Hosting. Some of the examples of managed applications hosting a WCF Service are Console, Windows Forms and WPF applications.

Self Hosting is very useful during the development and testing of applications but is rarely deployed in production scenarios. Self Hosting can also be used to support disconnected scenarios where a service agent invokes a locally self hosted service when the application is in disconnected mode.  In Self Hosting, the Service Host has to be instantiated at the time of the managed application startup and closed before the managed application shutdown. The Service Host in a managed application can be configured via App.Config file for service host base address and various end points. Managed application acting as a service host does not provide features like message based activation, mechanism to monitor service health or service host resources or recycling of the service host process upon detection of error conditions.

The security context for the Self Hosted WCF service is the identity under which the managed application runs.

A WCF Service hosted in a managed application can be exposed over TCP, HTTP, HTTPS, Named Pipe and MSMQ protocols.

The following code sample is an example of WCF Service being hosted in a managed application and the service host is initialized declaratively via App.Config file:

Using(ServiceHost serviceHost = new  ServiceHost(typeof(CalculatorService)))

{

     //Open the Service Host to start receiving messages

     serviceHost.Open();      

     // The service is now ready to accept requests 

     …..

   …..

     // Close the ServiceHost to shutdown the service.

     serviceHost.Close();

}

Code Sample 1: Creating a Service Host in a Managed Application

The base address and the endpoints for the service host have to be configured in the <services> sub section of the <system.serviceModel> section of the App.Config as shown below:  

<system.serviceModel>

    <services>

      <service

          name="SecureHosting.Samples.CalculatorService"

          behaviorConfiguration="CalculatorServiceBehavior">

        <host>

          <baseAddresses>

            <add baseAddress="http://localhost:9000/SecureHostingSamples/service"/>

          </baseAddresses>

        </host>

        <endpoint address=""

                  binding="wsHttpBinding"

                  contract="SecureHosting.Samples.ICalculator" />

        <endpoint address="mex"

                  binding="mexHttpBinding"

                  contract="IMetadataExchange" />

      </service>

    </services>

 

    <behaviors>

      <serviceBehaviors>

        <behavior name="CalculatorServiceBehavior">

          <serviceMetadata httpGetEnabled="True"/>

          <serviceDebug includeExceptionDetailInFaults="True" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

 

  </system.serviceModel>

Code Sample 2: App.Config for Declaratively Configuring a Service Host in a Managed Application

Alternatively, the base address and the service endpoints can be configured programmatically instead of App.Config file as shown in the code sample below:

// Create a ServiceHost for the CalculatorService type.

 using (ServiceHost serviceHost =

    new ServiceHost(typeof(CalculatorService),new

      Uri("http://localhost:9000/SecureHostingSamples/service")))                

 {

      

        //Configure the service with an end point

        serviceHost.AddServiceEndpoint(typeof(ICalculator),

           new WSHttpBinding(), "");

        // Open the ServiceHost to start receiving messages

         serviceHost.Open();

      ….

     ….

      ….

 

     //Close the service host to shutdown the service

        serviceHost.Close ();

}

Code Sample 3: Configuring a Service Host Programmatically in a Managed Application

Managed Windows Service

A managed windows service can host a WCF service.  In this mode of hosting, one of the ways to create the Service Host programmatically is to leverage the the OnStart event of the Windows Service. The Service Host can be closed during the OnStop event. The Windows Service that acts as a Service Host for a WCF Service inherits from the ServiceBase as well the WCF Service Contract interface. Unlike the self hosted applications, Windows Service provides the facility to manage the lifecycle of the service via the Service Control Manager (SCM) console but Windows Service Host does not provide a message based activation. The Windows Service also implements an installer class that inherits from the System.Configuration.Install.Installer class.  This allows the Windows Service to be installed via the Installutil tool.  The security context (service account for the Windows Service) for the WCF Service hosted in a Windows Service is configured via the installer class with the help of ServiceProcessInstaller class. SCM tool can be used later to maintain this service account for the Windows Service.

The Windows Service as a Service Host is a good option for WCF Services that implement long running processes. The WCF Service in this case can be managed via the SCM tool and is restarted automatically in case of a failure. A WCF Service hosted in a Managed Windows Service can be exposed over TCP, HTTP, HTTPS, Named Pipe and MSMQ protocols. 

The following code sample is an example of WCF Service being hosted in a Managed Windows Service and the Service Host is initialized declaratively via App.Config file.

public class CalculatorService : ServiceBase, ICalculator

{

     public ServiceHost serviceHost = null;

 

     public static void Main()

     {

          ServiceBase.Run(new CalculatorService());

     }

 

     public CalculatorService()

     {

          ServiceName = "WCFWindowsCalculatorService";

     }

 

     //Start the Windows service.

     protected override void OnStart(string[] args)

     {

          if (serviceHost != null)

          {

                serviceHost.Close();

          }

           // Create a ServiceHost for the Service

           serviceHost = new ServiceHost(typeof(CalculatorService));

 

           // Start Listening for the Messages

           serviceHost.Open();

      }

     

      //Stop the Windows Service

      protected override void OnStop()

      {

           if (serviceHost != null)

           {

              serviceHost.Close();

              serviceHost = null;

           }

      }

}

Code Sample 4: Creating a Service Host in a Managed Application

Similar to a self hosted application, the Service Host in a managed service can be configured either via the App.Config file or programmatically in the OnStart method of the Windows Service.

IIS

The IIS hosting option (IIS 5.1, IIS 6.0 and IIS 7.0) allows the WCF Services to be hosted in the App Domains inside the ASP.NET worker process.  IIS forwards the requests received for a WCF Service to the ASP.NET worker process.  IIS supports message based activation. The Service instance is created only after receiving the first message.  Hosting a WCF Service in IIS allows us to leverage features such as service configuration, service management, process health monitoring, idle time shutdown and worker process recycling. However when hosted in IIS (IIS 5.1 and IIS 6.0), only HTTP or HTTPS transport can be supported for the WCF Service. On Windows Server 2003, IIS hosting should be considered as the preferred option for deploying WCF services in production when the service has to be exposed over the HTTP or HTTPs protocols. 

The security context for the WCF Service hosted inside the ASP.NET worker process is provided by the service account under which the worker process runs.

Hosting a WCF Service in IIS requires creation of a .SVC file besides a WCF Service implementation. No specific Service Hosting code is required to be written unless a custom service host needs to be created via System.ServiceModel.Activation.ServiceHostFactory class. Virtual Applications are created and dlls and sources are deployed to the physical path associated with the virtual application. Virtual Directory are the default container whose physical path contain the resources. The configuration for the service endpoints has to be defined in the Web.Config.

The following code sample depicts a .SVC file that allows the WCF Calculator Service to be hosted in IIS.

<%@ServiceHost language=c# Debug="true" Service="SecureHosting.Samples.CalculatorService" %>

Code Sample 5: SVC File for Hosting WCF Service in IIS

The following code sample depicts the <system.serviceModel> section of the Web.Config file that is used to configure the WCF Calculator Service end points:

<system.serviceModel>

    <services>

      <service name="SecureHosting.Samples.CalculatorService"

               behaviorConfiguration="CalculatorServiceBehavior">

        <!-- This endpoint is exposed at the base address provided by host: http://localhost/securehostingsamples/service.svc  -->

        <endpoint address=""

                  binding="wsHttpBinding"

                  contract="SecureHosting.Samples.ICalculator" />

        <endpoint address="mex"

                  binding="mexHttpBinding"

                  contract="IMetadataExchange" />

      </service>

    </services>

 

    <!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->

    <behaviors>

      <serviceBehaviors>

        <behavior name="CalculatorServiceBehavior">

          <serviceMetadata httpGetEnabled="True"/>

          <serviceDebug includeExceptionDetailInFaults="True" />

        </behavior>

      </serviceBehaviors>

    </behaviors>

 

  </system.serviceModel>

Code Sample 6: Web.Config File for Hosting WCF Service in IIS

WAS

Windows Process Activation Service (WAS) is a new process activation feature available on Windows Longhorn Server and Windows Vista.  WAS enables IIS 7.0 to leverage message based activation for protocols such as TCP, MSMQ and Named Pipes in addition to the HTTP protocol. This provides all the benefits of IIS hosting such as message based activation, service configuration, service management, process health monitoring, idle time shutdown and worker process recycling.  Additionally WAS removes the limitation associated IIS (IIS 5.1 and IIS 6.0) service hosting that only HTTP transport can be supported. WAS along with IIS 7.0 allows applications that need to use the TCP, MSMQ and Named Pipe protocols to take advantage of the IIS hosting features.

Service deployment process for IIS 7.0/WAS is same as discussed earlier for IIS host.  However, the web sites need to be configured via the APPCMD utility to support non HTTP protocols. The following code sample illustrates the configuration of the default site for TCP, MSMQ and Named Pipe protocols: (You must start the command shell in “Run as Administrator” mode.)

%windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.tcp',bindingInformation='808:*']

%windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.msmq',bindingInformation='*']

%windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" -+bindings.[protocol='net.pipe',bindingInformation='*']

Code Sample 7: Configuring Web Sites for enabling WAS for non HTTP Protocols

After running the above command, APPCMD tool updates the configuration file for WAS ApplicationHost.Config:

system.applicationHost>

  <sites>

    <site name="Default Web Site" id="1">

      <bindings>

        <binding protocol="http"

                       bindingInformation="*:80:" />

        <binding protocol="net.pipe"

                       bindingInformation="*" />

        <binding protocol="net.tcp"

                       bindingInformation="808:*" />

        <binding protocol="net.msmq"

                       bindingInformation="*" />

      </bindings>

    </site>

  </sites>

</system.applicationHost>

Code Sample 8: ApplicationHost.Config file for WAS

In order to enable the TCP protocol (in addition to the HTTP protocol) for the “SecureHostingSamples” application, the following command should be run from an administrator shell:

%windir%\system32\inetsrv\appcmd.exe set app "Default Web Site/securehostingsamples" /enabledProtocols:http,net.tcp

Code Sample 9: Configuring Applications for enabling WAS for TCP and HTTP Protocols

Criteria for Choosing a WCF Service Host

Depending upon the target deployment platform and the protocols to be support by the WCF Service, the following criteria can be used for choosing a Service Host:

·         On Windows Longhorn Server, IIS 7.0 along with WAS should be used to host the WCF services  that need to support the HTTP, TCP, MSMQ and Named Pipe protocols.

·         On Windows Server 2003, IIS 6.0 should be used to host WCF services that need to be exposed over HTTP protocol. Managed Windows Service can be used in the production environment as a Service Host when the WCF Service has to support protocols like TCP, MSMQ and Named Pipe.

·         On Windows Vista, IIS 7.0 along with WAS should be used to host the WCF Services that need to support HTTP, TCP, MSMQ and Named Pipe protocols. Self hosting can be used for development environment or to support disconnected mode.

·         On Windows XP, IIS 5.1 should be used to host the WCF services that need to be exposed over HTTP protocol. Windows Service can be used as a Service Host when the WCF Service has to support protocols like TCP, MSMQ and Named Pipe. Self hosting can be used for development environment or to support disconnected mode.

The following table summarizes the various Service Host choices available for different deployment platforms:

S. No.

Deployment Platform

Transport Protocols to be Supported

Host Choice

Features

1

Windows Longhorn Server

·         HTTP

·         TCP

·         MSMQ

·         Named Pipe

IIS 7.0 along with WAS

·         Service Management

·         Message Based Activation

·         Process Health Monitoring

·         Idle Time Management

·         Process Recycling

2

Windows Server 2003

HTTP

IIS 6.0

·         Service Management

·         Message Based Activation

·         Process Health Monitoring

·         Idle Time Management

·         Process Recycling

3

Windows Server 2003

·         TCP

·         MSMQ

·         Named Pipe

Managed Windows Service

Service Management via SCM

4

Windows Vista

·         HTTP

·         TCP

·         MSMQ

·         Named Pipe

IIS 7.0 along with WAS

·         Service Management

·         Message Based Activation

·         Process Health Monitoring

·         Idle Time Management

·         Process Recycling

5

Windows XP

HTTP

IIS 5.1

·         Service Management

·         Message Based Activation

·         Process Health Monitoring

·         Idle Time Management

·         Process Recycling

6

Windows XP

·         TCP

·         MSMQ

·         Named Pipe

Managed Windows Service

Service Management via SCM

Table 1:  Criteria for Choosing a WCF Service Host

 

Selecting the Service Bindings

Before a service can be deployed in a production environment, appropriate bindings must be chosen for the service depending upon whether the service is deployed in an Intranet, Internet, Federated environment, windows only or a heterogeneous environment as well as the security and performance quality attributes for the service. Bindings for a service among other things allow us to define its security and authentication mode.  A WCF service can be assigned transport level security, message level security or a combination of transport and message level security. Similarly, a service can be defined with an authentication mode of None, Username, Windows, Certificates and IssuedToken. Authentication process between the client and the service includes the authentication of service to the client as well as the authentication of the client to the service.

Deploying a WCF Service over Windows Only Intranet
Windows Only Intranet with WCF Clients

In Windows only intranet environment and when all the service clients are WCF clients, the service can be deployed with the NetTCPBinding and Transport level security for achieving  maximum performance. NetTCPBinding by default uses transport level security over a TCP channel along with binary message encoding. In a Windows only intranet environment, ClientCredentialType can be set to Windows to enable Windows authentication.

<bindings>

  <netTcpBinding>

    <binding name="Binding1">

        <security mode="Transport" />

           <transport clientCredentialType="Windows"                       protectionLevel="EncryptAndSign"/>

        </security>

    </binding>

  </netTcpBinding>

</bindings>

Code Sample 9: Configuring a WCF Service NetTCPBinding

Interoperability with ASP.NET Web Service Clients

For interoperability with ASMX (ASP.NET Web Services) clients, the WCF service can be configured to use BasicHttpBinding with transport level security. HTTP/GET metadata should be enabled for the service in the service behavior section.

<bindings>

  <basicHttpBinding>

    <binding name="Binding1">

        <security mode="Transport" />

           <transport clientCredentialType="Windows"                            protectionLevel="EncryptAndSign"/>

        </security>

    </binding>

  </basicHttpBinding>

</bindings>

<behaviors>

  <serviceBehaviors>

    <behavior name="HttpGetMetadata">

        <serviceMetadata httpGetEnabled="true" />

    </behavior>

  </serviceBehaviors>

</behaviors>

Code Sample 11: Configuring a WCF Service to Interoperate with ASP.NET Web Service Client

Deploying a WCF Service over Internet or in a Heterogeneous Environment

For a WCF service that has to be exposed over internet or deployed in a heterogeneous environment and needs to potentially interact with the clients on non-windows platforms, BasicHttpBinding or WSHttpBinding can be used depending upon the level of conformance required with the commonly used security standards.

Interoperability with WS-I Basic Profile 1.1

If the WCF service has to be compatible with the WS-I Basic Profile standard, then BasicHttpBinding should be chosen. BasicHttpBinding is compatible with WS-I Basic Profile 1.1.

In order to support SOAP Message Security UserName Token Profile version 1.0, the WCF service should be configured with BasicHttpBinding with security mode of TransportWithMessageCredential and client credential type of UserName.

<basicHttpBinding>

  <binding name="Binding1">

     <security mode="TransportWithMessageCredential">

        <message clientCredentialType="UserName" />

     </security>

  </binding>

</basicHttpBinding>

Code Sample 12: Configuring a WCF Service to Interoperate with WS-I Basic Profile 1.1 Clients using UserName Security Token Profile 1.0

In the above example, the service authenticates to the client via SSL certificate and the client authenticates to the service via the UserName security token.  The transmission security is provided by HTTPS/SSL. If IIS is used as the Service Host, then the IIS can be used to configure and enable SSL. In the case of self hosted service, HTTPCFG tool can be used to configure the SSL certificate at the port level.

For compliance with the SOAP Message Security X.509 Security Profile version 1.0, the WCF service should be configured with the BasicHttpBinding with the security mode of Message and the client credential type of Certificate.

<bindings>

 <basicHttpBinding>

  <binding name="Binding1">

    <security mode= "Message" >

      <message  clientCredentialType="Certificate" />

   </security>

  </binding>

 </basicHttpBinding>

</bindings>

<behaviors>

 <serviceBehaviors>

   <behavior name="ServiceBehavior">

      <serviceCredentials>

          <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />

          <clientCertificate>

               <authentication certificationValidationMode="ChainTrust" />

          </clientCertificate>

      </serviceCredentials>

 </serviceBehaviors>

</behaviors>

Code Sample 13: Configuring a WCF Service to Interoperate with WS-I Basic Profile 1.1 Clients using X.509 Security Token Profile 1.0

In the above example, the service authenticates to the client via a service certificate that is configured as part of the service behavior and the client authenticates to the service via a X.509 security token (certificate) that is part of a chain trust.

Interoperability with WS-* Standards

If the WCF service has to be compatible with the WS-* standards such as WS-Addressing, WS-Security, WS-SecureConversation and WS-Trust, then WSHttpBinding should be chosen.

In order to support SOAP Message Security UserName Token Profile version 1.1, the WCF service should be configured with WSHttpBinding with security mode of Message and client credential type of UserName.

<wsHttpBinding>

  <binding name="Binding1">

     <security mode="Message">

        <message clientCredentialType="UserName" />

     </security>

  </binding>

</wsHttpBinding>

Code Sample 14: Configuring a WCF Service to Interoperate with WS-* Clients using UserName Security Token Profile 1.1

Additionally, service certificate should also be configured as part of the service behavior section in the service configuration.

When a WCF service has to be exposed over extranet to a trusted business partner, typically WSHttpBinding along with certificates based authentication mechanism can be used. For compliance with the SOAP Message Security X.509 Security Token Profile version 1.0, the WCF service should be configured with the WSHttpBinding with the security mode of Message and the client credential type of Certificate.

<wsHttpBinding>

  <binding name="Binding1">

    <security mode= "Message" >

      <message  clientCredentialType="Certificate" />

   </security>

  </binding>

</wsHttpBinding>

Code Sample 15: Configuring a WCF Service to Interoperate with WS-* Clients using X.509  Security Token Profile 1.1

Deploying a WCF Service in a Federated Environment

In a Federated environment, the client obtains the security token from a security token service (STS) that is trusted by the WCF service. In this scenario, the WCF Service should be configured with the WSFederationHttpBinding. The security element of the WCF service also contains the address of the end point used to retrieve the metadata of the STS. In the service credentials section of the service behavior, the certificate used by STS for signing the security token should be added to the list of known certificates.

<bindings>

 <wsFederationHttpBinding>

  <binding name="Binding1">

    <security mode ="Message">

            <message issuedKeyType ="SymmetricKey" issuedTokenType ="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1" >

              <issuerMetadata address ="http://localhost:8888/sts/mex" >

                <identity>

                  <certificateReference storeLocation ="CurrentUser"

                                        storeName="TrustedPeople"

                                        x509FindType ="FindBySubjectDistinguishedName"

                                        findValue ="CN=STS" />

                </identity>

              </issuerMetadata>

            </message>

          </security>

  </binding>

 </wsFederationHttpBinding>

</bindings>

<behaviors>

   <serviceBehaviors>

      <behavior name ="ServiceBehaviour" >

          <serviceCredentials>

            <issuedTokenAuthentication>

              <knownCertificates>

                <add storeLocation ="LocalMachine"

                     storeName="TrustedPeople"

                     x509FindType="FindBySubjectDistinguishedName"

                     findValue="CN=STS" />

              </knownCertificates>

            </issuedTokenAuthentication>

            <serviceCertificate storeLocation ="LocalMachine"

                                storeName ="My"

                                x509FindType ="FindBySubjectDistinguishedName"

                                findValue ="CN=localhost"/>

          </serviceCredentials>

      </behavior>

   </serviceBehaviors>

</behaviors>

Code Sample 16: Configuring a WCF Service to operate in a Federated Environment

Provisioning the SSL Certificate

When a WCF service relies on transport level security (Security Mode = “Transport”), SSL certificate has to be set up and enabled for the WCF Service. If the WCF Service is hosted in IIS, then the SSL certificate can be configured via the IIS manager. If the service is hosted in a non IIS host, then the certificate needs to be configured using HTTPCFG tool in the following manner:

Httpcfg set ssl  -I  [IP Address:Port] –h [Certificate SHA1 Thumbprint] –Personal

Code Sample 17: Provisioning a WCF Service with SSL Certificate

In the above command, it is assumed that a certificate is already installed in the local machine under the personal store. IP Address:Port is the address and the port respectively of the WCF service end point. The SHA1 thumbprint of the certificate can be obtained by examining the certificate using the MMC console.

Selecting a Service Account and Provisioning It

Service Account Types

The service account that a Service Host is configured to run provides the necessary security context for the WCF Service. During the deployment of WCF Services, the principle of least privilege should be used so that the Service Host is configured with minimum privileges that are necessary for it to run. The following are various service accounts that can be used to configure the security context for a Service Host:

Local System Account

The Local System account is a predefined local account that can start a service and provide the security context for that service. It is a powerful account that has full access to the computer, including the directory service when used for services running on domain controllers. The account acts as the host computer account on the network and as such has access to network resources just like any other domain account. On the network, this account appears as DOMAIN\<machine name>$. If a service logs on using the Local System account on a domain controller, it has Local System access on the domain controller itself, which, if compromised, could allow malicious users to change anything in the domain they wanted. Windows Server 2003 configures some services to log on as the Local System account by default. The actual name of the account is NT AUTHORITY\System, and it does not have a password that an administrator needs to manage.

Local System Account is a very high-privileged account and in most cases should not be used as the service account for a WCF Service.  The Local System account has full administrative privileges on the local computer. Therefore, if an attacker is able to execute code on the computer by exploiting a security hole in IIS, he or she can do so with administrative privileges.

Local Service Account

The Local Service account is a special built-in account that has reduced privileges similar to an authenticated local user account. This limited access helps safeguard the computer if an attacker compromises individual services or processes. A service that runs as the Local Service account accesses network resources as a null session; that is, it uses anonymous credentials. The actual name of the account is NT AUTHORITY\LocalService, and it does not have a password that an administrator needs to manage.

Local Service Account is a low privileged account that can be used when the service does not need access to the network resources and remote database.

Network Service Account

The Network Service account is a special built-in account that has reduced privileges similar to an authenticated user account. This limited access helps safeguard the computer if an attacker compromises individual services or processes. A service that runs as the Network Service account accesses network resources using the credentials of the computer account in the same manner as a Local System service does. The actual name of the account is NT AUTHORITY\NetworkService, and it does not have a password that an administrator needs to manage.

Network Service Account is a low privileged account that can be used when the service needs access to the network resources and remote database.

Local User Account

The local user account is an account on the application server where the WCF service is deployed and has been granted the necessary permissions on the resources such as files, MSMQ, event logs as required for successfully running the service.

These accounts have very limited privileges on the local computer unless they are specifically granted higher privileges or are added to groups that already possess those privileges.

Mirrored local user account with same user code and password can be used when the service needs to access resources on a remote server that is in a separate domain with no trust or the remote is behind a firewall that prevents the Kerberos authentication.

Local Administrator Account

This local administrator account includes the built-in Administrator or any other user accounts that are added to the built-in Administrators group. Members of this group have full and unrestricted access to the local computer.

Using Local Administrator Account or making a Service Account part of the Local Administrator group should be avoided at all cost as it represents a severe security risk.

Domain User Account

Domain user account includes accounts that you create in the domain, for example, by using the Active Directory Users and Computers management console. These accounts have limited privileges in the domain.

Domain User Accounts can be used as the service accounts for the following reasons:

·         Domain accounts allow us to trace the security events to corresponding applications thus providing an improved audit trail

·         Domain accounts allow us to provide custom security permissions for certain application pools

·         When services belong to multiple customers are hosted on a single server in a SAAS environment, having those services run under separate service accounts provides greater security and isolation

The domain user account needs to be added to the IIS_WPG group on IIS 6.0 After a domain user account has been set as the identity of the application pool, the setspn utility needs to be run to create a Service Principal Name (SPN) for the domain account in the following manner:

setspn -A <ServiceName>/<HostName> domain\customAccountName

Code Sample 18: Running the setspn utility for the domain service account

In the above example <ServiceName>/<HostName> is the SPN for the domain account domain/customAccountName.  The WCF client which consumes a WCF service running under a domain user account (service account), needs to identify the SPN in the client configuration in the following manner:

<client>

  <endpoint name="EndPoint1" address="…."

    binding = "wsHttpBinding" contract="…">

    <identity>

      <servicePrincipalName value=’<ServiceName>/<HostName>’ />

    </identity>

  </endpoint>

</client>

Code Sample 19: Setting the Identity of the service for Kerberos Authentication in the WCF Client Configuration file

When the WCF service host runs under the context of system accounts such as Local System, Local Service or Network Service, the default SPN used is Host/<HostName>.

Domain Administrator Account

Domain administrator includes the built-in domain Administrator account that you create and use when you first install Active Directory. It includes any other user accounts that you subsequently create and add to the built-in local Administrators group or to the Domain Admins or Enterprise Admins groups. Members of these groups have complete and unrestricted access to the domain and, in the case of the Enterprise Admins group, to the entire forest.

Using Domain Administrator Account or making a Service Account part of the Domain Administrator group should be avoided at all cost as it represents a severe security risk.

Provisioning of Service Accounts

The method to be used to provision the service account for a WCF Service depends upon the choice of the Service Host: 

Self Host

The security context for the self hosted applications is provided by the windows user logged on to the desktop. No separate service account is required to be provisioned in this situation.

Managed Windows Service

The service account for the managed windows service can be configured in the installer class of the windows service as shown below:

    [RunInstaller(true)]

    public class ProjectInstaller : Installer

    {

        private ServiceProcessInstaller process;

        private ServiceInstaller service;

 

        public ProjectInstaller()

        {

            process = new ServiceProcessInstaller();

            process.Account = ServiceAccount.LocalSystem;

            service = new ServiceInstaller();

            service.ServiceName = "WCFWindowsCalculatorService";

            Installers.Add(process);

            Installers.Add(service);

        }

    }

Code Sample 20: Configuring a Service Account for Managed Windows Service

When the managed windows service is installed via the Installutil tool, the service is created with the configured service account. Once the managed windows service has been installed, the service account can be configured via the SCM tool.

IIS 5.1

In IIS 5.1, the Service Host can be configured via the Username and Password elements of the <processModel> element of the Machine.Config. The Username and Password can be encrypted and stored in the registry for increased security.

IIS 6.0

IIS 6.0 Service Hosts can be configured to run under a service account by configuring the identity account for the worker process at the Application Pool level.

Configuring the worker process identity via IIS Manager:

To change the account under which an application pool runs using IIS Manager

·         In IIS Manager, expand the local computer, expand Application Pools, right-click the application pool, and then click Properties.

·         Click the Identity tab, and click either Predefined or Configurable. Predefined refers to standard service names, such as Network Service (the default), LocalSystem, or Local Service. Configurable refers to registered user names.

·         If you click Predefined, choose a predefined account from the list box.

·         If you click Configurable, in the User name and Password boxes, type the user name and password of the account under which you want the worker process to run in.

Note: The service account configured for the IIS worker process must be a member of the IIS_WPG user group.  This group provides the minimum set of privileges and permissions required to start and run a worker process on a Web server. On a clean installation of IIS 6.0, the IIS_WPG group contains the Network Service, Local Service, Local System accounts.

Configuring the worker process identity via a Script:

The following script can be used to configure the worker process identity for an application pool called SecureAppPool:

Var appPool = GetObject("IIS://localhost/w3svc/AppPools/SecureAppPool" );

// Tell IIS to use configurable identity for worker process

appPool.AppPoolIdentityType = 3;

// Set username

appPool.WAMUserName = "myuser";

// Set password

appPool.WAMUserPass = "myuserpass";

// Save changes to the IIS metabase

appPool.SetInfo();

Code Sample 21: Configuring a Service Account for IIS 6.0 Worker Process

WAS/IIS 7.0

The service account configuration process for WAS/IIS 7.0 Service Host is same as configuring the identity for the application pool in IIS 6.0 as described above. In IIS 7.0, a new Windows built-in group called IIS_IUSRS replaces the local IIS_WPG group. However, IIS 7.0 automatically add the IIS_IUSRS membership to the worker processes token at runtime. Hence, the accounts that have been defined to run as 'application pool identities' no longer need to explicitly be part of the IIS_IUSRS group.

Impersonation in WCF Service

Impersonation allows the WCF Service operations to execute under the security context of the client instead of the security context of the service account under which the service host is running. Impersonation is available only when the ClientCredentialType of Windows is used. IIS impersonation is supported in aspNetCompatabilityMode. User needs to opt into the impersonation.

Impersonation Mechanisms

There are two main mechanisms to implement impersonation in a WCF Service:

Impersonation in a Service Operation via Declarative Mode

Impersonation can be implemented in the WCF Service by decorating the OperationBehavior attribute of the service operation in the following manner:

[OperationBehavior(Impersonation = ImpersonationOption.Required)]

public double Subtract(double n1, double n2)

{

      double result = n1 - n2;

      return result;

}

Code Sample 22: Declarative Implementing the Impersonation in a WCF Service

OperationBehavior attribute for Impersonation property can be set to the following values:

•   Impersonation.Required

This setting allows the Service Operation to run under the security context of the client identity.

•   Impersonation.Allowed

This setting allows the Service Operation to run under the security context of the client identity however, when a service has higher credentials than the remote client, the credentials of the service are used if the Impersonation property is set to Allowed. That is, if a low-privileged user provides its credentials, a higher-privileged service will execute the method with the credentials of the service, and will be able to use resources that the low-privileged user would otherwise not be able to use.

Impersonation in a Service Operation via Imperative Mode

Impersonation can be implemented in the service operation in the following manner:

public double Add(double n1, double n2)

{

       double result = n1 + n2;

                   

      if(

      ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel

       ==

      System.Security.Principal.TokenImpersonationLevel.Impersonation)

      {

           System.Security.Principal.WindowsIdentity  identity =

                ServiceSecurityContext.Current.WindowsIdentity;

           using (identity.Impersonate())

           {

                //Access file resources in the security context

                //of the client

           }

       }

       else

       {

            //Log error and thorw an exception that the client

            //impersonation level is not high enough for this

            //operation

       }

 

        return result;

   }

Code Sample 23: Imperatively Implementing the Impersonation in a WCF Service

TokenImpersonationLevel has to be set on the client side and can have the following values:

·         Anonymous: The server process cannot obtain identification information about the client, and it cannot impersonate the client. 

·         Delegation: The server process can impersonate the client's security context on remote systems. 

·         Identification: The server process can obtain information about the client, such as security identifiers and privileges, but it cannot impersonate the client. This is useful for servers that export their own objects, for example, database products that export tables and views. Using the retrieved client-security information, the server can make access-validation decisions without being able to use other services that are using the client's security context. 

·         Impersonation: The server process can impersonate the client's security context on its local system. The server cannot impersonate the client on remote systems. 

·         None: An impersonation level is not assigned. 

TokenImpersonationLevel can be set on the client side in the service proxy in the following manner:

// Create a client

CalculatorClient client = new CalculatorClient();

            client.ClientCredentials.Windows.AllowedImpersonationLevel

= System.Security.Principal.TokenImpersonationLevel.Impersonation;

Code Sample 24: Specifying the Impersonation Level in the WCF Client

Impersonation Guidelines

·         Impersonation should generally be avoided as it presents a security threat and also adds to the performance overheads.

·         Impersonation should only be used for a temporary period of time when service needs to run under the security context of the caller to access protected domain resources such as directories, files, database etc.

·         When a WCF Service Host has been configured to run under a lower privilege service account such as Local Service or Network Service, impersonation could cause a service to execute under elevated privileges (that of the client) and this could result in security threat.

Limitations

·         Impersonation is only supported when the WCF service uses authentication mode of Windows Credentials.

·         When the client and service are running on the same computer and the client is running under a system account (that is, Local System or Network Service), the client cannot be impersonated when a secure session is established with stateful Security Context tokens.

·         On computers running Windows Server 2003, impersonation is supported only if the Host.exe application has the Impersonation privilege. (By default, only administrators have this permission.) To add this privilege to an account the service is running as, go to Administrative Tools, open Local Security Policy, open Local Policies, click User Rights Assignment, and select Impersonate a Client after Authentication and double-click Properties to add a user or group.

Common Attack Vectors in a WCF Service

A WCF service that is deployed in a production environment can be subjected to various attack vectors and should be configured to guard against them. Prior to deploying a service in production, a proper threat modeling should be carried out to identify and mitigate the attack vectors listed below. The following are the most common attack vectors that a WCF Service can be subjected to:

Elevation of Privilege Attacks

Elevation of privilege attack allows an attacker to obtain special security privileges that are not available to a general user. The following considerations should be taken into account to minimize the occurrence of the elevation of privilege attacks:

·         Impersonation in the service host should be sparingly used.  In case impersonation is absolutely required, it must be programmatically turned on for a limited time and reverted back when done.

·         Using state-full security sessions provides some level of protection against elevation of privilege attacks. State-full security sessions can be enabled via EstablishSecurityContext property.

EstablishSecurityContext property can be set declaratively in the following manner:

<wsHttpBinding>

  <binding name="wsHttp">

    <security mode="Message">

      <message establishSecurityContext="true" />

    </security>

  </binding>

</wsHttpBinding>

Code Sample 25: Setting the EstablishSecurityContext Property Declaratively

EstablishSecurityContext property can be set programmatically in the following manner:

WSHttpBinding binding = new WSHttpBinding();

 

binding.Security.Mode = SecurityMode.Message;

binding.Security.Message.EstablishSecurityContext = true;

Code Sample 26: Setting the EstablishSecurityContext Property Programmatically

Note: By default, the EstablishSecurityContext property is set to true when using message level security.

Denial of Service Attacks

In a Denial of Service attack, the attacker floods the service with numerous calls or large data objects in such a manner that the service becomes unusable.  The following considerations should be taken into account to minimize the occurrence of denial of service attacks:

·         The WCF service should be reviewed and profiled any potential memory leaks. Memory leaks are generally exploited by denial of service attacks.

·         When certain XML operations in the service that use the XMLReader class and call the NamespaceUri, Localname or Prefix property for each item, the returned string is added to a NameTable object. XMLReader uses this class internally. This represents a potential memory leak. One way to mitigate this threat is to implement a derived NameTable  class where on reaching a maximum limit a alert message is logged to event log.  The following code demonstrates the configuration of a XmlReader with a CustomNameTable object:

CustomNameTable nameTable = new CustomNameTable();

nameTable.MaxNameTableSize = 100;

XmlReaderSettings settings = new XmlReaderSettings();

settings.NameTable = nameTable;

XmlReader reader = XmlReader.Create("book.xml", settings);

Code Sample 27: Configuring the XmlReader object with a CustomNameTable Object

In the above example, the CustomNameTable class has been derived from NameTable class and logs a message when the maximum size configured for the NameTable exceeds.

public override string Add(string key)

{

     if (currentNameTableSize > maxNameTableSize)

     {

            LogNameTableOverflowMessage();

       }

 

       string retVal = base.Add(key);

       currentNameTableSize += retVal.Length;

          

       return retVal;

}

Code Sample 28: Overriding the Add method of the NameTable class in the CustomNameTable Class

·         Attacker can send multiple requests to the service and this can cause the service to become unavailable. The following parameters of the LocalServiceSecuritySettings class should be set to prevent this attack:

·         InactivityTimeout: Manages the maximum time the service keeps a secure conversation alive without receiving an application message from the client for the conversation. This quota prevents clients from establishing secure conversations at the service, thereby causing the service to maintain state per client, but never using them.

·         MaxCachedCookies: Manages the maximum number of time-bounded SecurityContextTokens that are cached by the server after doing SPNego or SSL negotiation.

·         MaxPendingSessions: Manages the maximum number of secure conversations that are established at the server but for which no application messages have been processed. This quota prevents clients from establishing secure conversations at the service, thereby causing the service to maintain state per client, but never using them.

InActivityTimeout, MaxCachedCookies, MaxPendingSessions parameters have to be configured under the <security> element and the <localServiceSettings> sub-element of the binding configuration for the client and the service.

<localServiceSettings inactivityTimeout="00:05:00"

                      maxCachedCookies="500"

                      maxPendingSessions="500"

/>

Code Sample 29: LocalServiceSettings element in the Client and the Service Configuration Files

·         Attacker can send multiple invalid requests to the service and cause the audit log to be filled up.  This situation can cause the audit log calls to throw exceptions and result in the failure to process the user requests.  To mitigate this security threat, the SuppressAuditFailure property should be set to true.  When the “SuppressAuditFailure property is set to true, any failure to write to the event log will not result in any exception being thrown.  The following code snippet demonstrates the way to set the serviceSecurityAudit behavior in the service configuration file.

<serviceBehaviors>

        <behavior name ="ServiceBehaviour" >

          <serviceSecurityAudit

            auditLogLocation="Application"

            suppressAuditFailure="true"

            serviceAuthorizationAuditLevel="SuccessOrFailure"

            messageAuthenticationAuditLevel="SuccessOrFailure" />

   ….

  </behavior>

</serviceBehaviors>

Code Sample 30: ServiceSecurityAudit element in the Service Configuration File

Replay Attacks

During a replay attack, the attacker steals the message exchanged between two entities and sends these messages to other entities.  The following considerations should be taken into account to minimize the occurrence of the replay attacks:

·         Message level security provides for message identifiers in the form of Nonce which is normally cached on the server side to detect replay attacks. Since replay caches are not shared across web farms, an attacker can replay a message to a service across different nodes in a web farm.  In order to prevent this threat, the service should be configured to use the transport level security or state-full security context tokens should be enabled along with the message level security.

·         Reflection attacks are a kind of replay attacks where an attacker replays the message back to the sender. WCF default bindings use WS-Addressing and the sender expects the response message contain a RelatesTo field that should match to the MessageId field in request message. Custom bindings that do not use WS-Addressing are susceptible to reflection attacks.    In order to prevent this attack, custom bindings should use WS-Addressing headers. 

WS-Addressing headers in the SOAP envelope can be controlled via the textMessageEncoding sub-element of the binding element in the following manner:

<textMessageEncoding maxReadPoolSize="211"

    maxWritePoolSize="2132"

    messageVersion="Soap12Addressing10"

    textEncoding=”utf-8” />

Code Sample 31: ServiceSecurityAudit element in the Service Configuration File

Information Disclosure Attacks

Information disclosure attack allows an attacker to obtain additional information about an application which can be used to compromise the security. The following considerations should be taken into account to minimize the occurrence of the information disclosure attacks:

·         When message level security is enabled over HTTP protocol, the HTTP headers remain unprotected and this can be mitigated by using HTTPS along with the message level security.

·         Incorrect exception handling strategy can cause sensitive service information to be disclosed at the client side.  Exception shielding pattern should be used to mitigate this.

·         Memory dumps of the service can contain sensitive information such as claims which are used to perform server side authorization.  Such memory dumps should not be shared with un-trusted sources.

·         When a certificate is used to authenticate a client, the certificate is transferred in clear inside the soap header. To mitigate this threat, TransportWithMessageCredential mode should be used for the WCF messages where the entire message is encrypted with transport level security. This can be done in the following manner:

<wsHttpBinding>

<binding name="Binsing1">

        <security mode="TransportWithMessageCredential" />

           <message clientCredentialType="UserName" />

        </security>

</binding>

</wsHttpBinding>

Code Sample 32: Configuring a Binding to Use TransportWithMessageCredential security mode

Tampering Attacks

During a tampering attack, the attacker alters the contents of the message and uses the altered message for unintended use. The following considerations should be taken into account to minimize the occurrence of the tampering attacks:

·         Enable the message level security wherever possible.  Use of WS-Security protocol provides protection against certain message tampering scenarios.

·         Do not disable the WS-Addressing by setting the addressing property to disabled. WS-Addressing allows the receiver of the message to verify the sender of the message.

 

Provisioning Required on Infrastructure Resources

This section highlights the provisioning that is required on various operating system resources such as MSMQ, Event Logs, Performance Counters and Files for a WCF service to operate on such resources.

MSMQ

The following are the provisioning that is required to enable WCF client/service to perform MSMQ based messaging:

·         Queues can be created via Computer Management->Service and Applications->Message Queuing tool. When a queue is created, the default permission is that everyone can send messages to this queue. For tighter security, you can change the default security permissions for the queue.

·         Queues can also be created programmatically from the WCF Service as shown below:

// Get MSMQ queue name from app settings in configuration

string queueName = ConfigurationManager.AppSettings["queueName"];

 

      // Create the transacted MSMQ queue if necessary.

      if (!MessageQueue.Exists(queueName))

   {

           MessageQueue.Create(queueName, true);

   }

Code Sample 33: Creating Message Queues from WCF Service

·         While creating the queues, the queue can be marked as an Authenticated Queue which indicates that the queue requires authentication of the client sending messages to the queue. This ensures that no un-authenticated messages are accepted in the queue.

·         MSMQ Queues can also be secured using a Windows identity registered with Active Directory. When installing MSMQ, you can install Active Directory integration. Active Directory integration requires the machine to be part of a Windows Domain network.

·         The NetMsmqBinding and MsmqIntegrationBinding are using by a WCF MSMQ service to communicate with the MSMQ queues. The MSMQAuthenticationMode property dictates whether Windows Authentication or certificate based authentication would be used. It can be set to WindowsDomain or CertificateValidationMode. The MsmqProtectionLevel property provides the protection against message tempering.  It can be set to Sign or SignandEncrypt or None.

Event Log
Event Sources

Normally service accounts do not have permissions to create new event sources, but they can write to already existing event sources.  It is a good practice to create the new event sources during the application install time or as an alternative manually create event sources in the registry.

Application Event Log

All normal accounts have access to read and write to the Application Event Log and no special provisioning is required.

Security Event Log

To be able to write to the security event log, the service account under which the Service Host is running must possess SeAuditPrivilege. By default, only Local System and Network Service accounts have such a privilege.

To manage the Security log functions read and delete requires the SeSecurityPrivilege. By default, only administrators have such privilege.

Performance Counters

In order that the WCF Service can update performance counters, one of the following needs to be done:

·         Service Account for the Service Host  should be made a member of group "Performance Log Users"

·         Service Account for the Service Host should have full access to the registry key HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib.

File System

·         Service Account for the Service host should be granted explicit read/write access on any files that are read from or written to by the WCF Service.

·         Adding the Application Pool Service Account on Windows Server 2003 to the IIS_WPG user group provides the minimum set of privileges and permissions required to start and run a worker process on a Web server. On Vista/Longhorn, the IIS_IUSRS group provides the minimum set of privileges and permissions required to start and run a worker process on a Web server. . However, IIS 7.0 automatically add the IIS_IUSRS membership to the worker processes token at runtime. Hence, the accounts that have been defined to run as 'application pool identities' no longer need to explicitly be part of the IIS_IUSRS group.

Conclusion

When deploying a WCF Service in a Windows Longhorn and Vista based production environment, IIS should be the preferred choice for the service host as it provides a large number of features for efficient service management as well as supports all the commonly used transport protocols such as HTTP, TCP, MSMQ, Named Pipe etc. Depending upon the deployment environment (Intranet, Internet, Federated, Windows Only or Heterogeneous) appropriate service bindings should be chosen. In order to reduce the attack surface, WCF Service Host should be provisioned with a least privileged service account that is required to run the service successfully. Impersonation should be used only for a limited period of time for accessing resources that cannot be accessed by the service account. The WCF Service should be configured appropriately to mitigate the risks associated with the common attack vectors. Finally, the service account for the WCF Service should be granted appropriate access rights on the infrastructure resources such as MSMQ, Event Log, Performance Counters and the File System so that the WCF service can run successfully.

About the Author

Girish Phadke is a Consultant in at Tata Consultancy Services Ltd!href(http://www.microsoft.com/MSPress/books/4293.asp). His main focus areas are developing SOA and SAAS architecture using Microsoft Technologies. 

About the Reviewers

Jan Alexander is a senior program manager at Microsoft working on authentication and authorization for distributed applications. He is also active in various standard bodies working on WS-* standards primarily in the security area.

Ram Poornalingam is a program manager in the Connected Systems Division and is currently working in the hosting space for Windows Communication Foundation.

Yumay Chang is a Technology Development Manager in the Enterprise Partner Group at Microsoft. She leads the partner strategy on SOA and Business Process Management and supports partner in their adoption of Microsoft technologies in this space.

 

Show:
© 2015 Microsoft