Message Security

patterns & practices Developer Center

If your WCF application passes sensitive data over networks, consider the threats of eavesdropping, tampering, and unauthorized callers accessing your endpoint. In an Internet scenario where you do not have control over the intermediate systems, consider using message security.

Consider the following guidelines for choosing message security:

  • If you need to support clients over the Internet, consider using message security.
  • If there are intermediaries between the client and service, consider using message security.
  • If you need to support selective message protection, use message security.
  • If you need to support multiple transactions per session using Secure Conversation, use message security.
  • Do not pass sensitive information in SOAP headers when using HTTP transport and message security.
  • If you need to support interoperability, consider setting negotiateServiceCredential to false.
  • If you need to streamline certificate distribution to your clients, consider negotiating the service credentials.
  • If you need to limit the clients that will consume your service, consider setting negotiateServiceCredential to false.

Each of these guidelines is described in the following sections.

If you need to support clients over the Internet, consider using message security

Use message security when your clients are deployed over the Internet and you cannot rely on transport security (SSL). Message security provides end-to-end security in the following ways:

  • Because SSL does not provide protection for the initial client-server handshake, a man-in-the-middle attack can go undetected.
  • You have less control over the communication between the client and service across the Internet. There is a chance of having intermediaries, which might break transport security.

The downside of using message security is potentially decreased performance due to the fact that each message much be encrypted individually. Large message packets especially can create lag. You can use wsHttpBinding, which by default uses message security and also supports interoperability because it uses text encoding.

Additional Resources

If there are intermediaries between the client and service, consider using message security

Use message security in scenarios where there may be intermediaries inspecting the message before the final delivery. You can protect your messages by using message security to encrypt and sign your messages. By encrypting your messages, you protect your sensitive data from being compromised. By signing your messages, you protect the client and service from tampering and man-in-the-middle attacks by protecting message integrity.

The following configuration snippet shows how to use message security to protect the credentials when using wsHttpBinding:

<wsHttpBinding>
  <binding name="MessageAndUserName">
    <security mode="Message">
      <message clientCredentialType="UserName" algorithmSuite="Default" />
    </security>
  </binding>
</wsHttpBinding>

Additional Resources

If you need to support selective message protection, use message security

If you need signatures but not encryption on your messages, use message security to allow selective reduction of the protection level. This gives you more flexibility than transport security, especially if you do not need to protect specific bigger message payloads over the network.

Be aware that turning off encryption will allow an attacker to view the content of your messages, including credentials or other sensitive information.

You can set the protection level to signatures only on the entire service as follows:

[ServiceContract(ProtectionLevel=ProtectionLevel.Sign]
public interface IService
{
string GetData(int value);
}

You can set the protection level to signatures only on a single method at a time as follows:

[OperationContract(ProtectionLevel=ProtectionLevel.Sign]
string GetData(int value);

Additional Resources

If you need to support multiple transactions per session using Secure Conversation, use message security

If your WCF clients need to exchange multiple messages with the WCF service, you can use the Secure Conversation feature for improved performance. Using Secure Conversation means the token negotiation and authentication happens only once for all the requests in a session.

Secure Conversation is enabled with message security on all the standard bindings that support the WS-Security specification (for example, WsHttpBinding, NetTcpBinding, and netMsmqBinding).

The following configuration example shows the Secure Conversation turned on:

...
<wsHttpBinding>
  <binding name="NewBinding0">
    <security>
      <message establishSecurityContext="true" />
    </security>
  </binding>
</wsHttpBinding>
...

Additional Resources

Do not pass sensitive information in SOAP headers when using HTTP transport and message security

Do not use message security if you need to pass sensitive information in Simple Object Access Protocol (SOAP) headers over the HTTP protocol. Instead, use transport security to protect sensitive data passed in SOAP headers, such as user identities passed for auditing purposes.

Information contained in SOAP headers is sent in plain text format and can be stolen if you use message security. SOAP header information is signed by default using message security, so the information can be read but cannot be spoofed.

Additional Resources

If you need to support interoperability, consider setting negotiateServiceCredential to false

If you need to support clients that do not understand the WS-Trust and WS-SecureConversation specifications, set the negotiateServiceCredential attribute to false.

For Anonymous, Username, or Certificate client credential types, setting this property to false implies that the service certificate must be made available to the client out of band, and that the client must specify the service certificate to be used. In the case of Windows credentials, setting this property to false causes an authentication based on KerberosToken. This requires that the client and service both be part of a Kerberos domain.

The following is a configuration example:

<wsHttpBinding>
  <binding name="MessageAndUserName">
    <security mode="Message">
      <message clientCredentialType="UserName" negotiateCredentials=”false” algorithmSuite="Default" />
    </security>
  </binding>
</wsHttpBinding>

Additional Resources

If you need to streamline certificate distribution to your clients, consider negotiating the service credentials

Consider enabling negotiateServiceCredential if you need to streamline certificate distribution to your clients for message encryption. This option is only available with wsHttpbinding. Keep in mind that non-Microsoft clients will not be able to consume your service if you enable this option. Also consider that there is a performance penalty of negotiating credentials, due to message exchange. Additionally, consider that allowing negotiation of service credentials is less secure, thereby allowing any client to consume your service.

The following binding configuration shows how to set this option:

<binding name="BindingMessage">
   <security mode="Message">
      <message clientCredentialType="Windows" 
negotiateServiceCredential="true" />
   </security>
</binding>

Additional Resources

If you need to limit the clients that will consume your service, consider setting negotiateServiceCredential to false

If you want to limit the clients that can consume your service, consider setting negotiateServiceCredential to false. This option will force you to install a certificate on the client, in addition to a service certificate with a public key. On the service, you will need to install a certificate plus the client certificate with the public key. Negotiation of service credentials is only available with wsHttpBinding.

The following binding configuration shows how to set this option:

<binding name="BindingMessage">
   <security mode="Message">
      <message clientCredentialType="Windows" 
negotiateServiceCredential="false" />
   </security>