Best Practices for Security in WCF
The following sections list the best practices to consider when creating secure applications using Windows Communication Foundation (WCF). For more information about security, see Security Considerations, Security Considerations for Data, and Security Considerations with Metadata.
Identify Services Performing Windows Authentication with SPNs
Services can be identified with either user principal names (UPNs) or service principal names (SPNs). Services running under machine accounts such as network service have an SPN identity corresponding to the machine they're running. Services running under user accounts have a UPN identity corresponding to the user they're running as, although the setspn
tool can be used to assign an SPN to the user account. Configuring a service so it can be identified via SPN and configuring the clients connecting to the service to use that SPN can make certain attacks more difficult. This guidance applies to bindings using Kerberos or SSPI negotiation. Clients should still specify an SPN in the case where SSPI falls back to NTLM.
Verify Service Identities in WSDL
WS-SecurityPolicy allows services to publish information about their own identities in metadata. When retrieved via svcutil
or other methods such as WsdlImporter, this identity information is translated to the identity properties of the WCF service endpoint addresses. Clients which do not verify that these service identities are correct and valid effectively bypass service authentication. A malicious service can exploit such clients to execute credential forwarding and other "man in the middle" attacks by changing the identity claimed in its WSDL.
Use X509 Certificates Instead of NTLM
WCF offers two mechanisms for peer-to-peer authentication: X509 certificates (used by peer channel) and Windows authentication where an SSPI negotiation downgrades from Kerberos to NTLM. Certificate-based authentication using key sizes of 1024 bits or more is preferred to NTLM for several reasons:
the availability of mutual authentication,
the use of stronger cryptographic algorithms, and
the greater difficulty of utilizing forwarded X509 credentials.
For an overview of NTLM forwarding attacks, go to https://msdn.microsoft.com/msdnmag/issues/06/09/SecureByDesign/default.aspx.
Always Revert After Impersonation
When using APIs that enable impersonation of a client, be sure to revert to the original identity. For example, when using the WindowsIdentity and WindowsImpersonationContext, use the C# using statement or the Visual Basic Using statement, as shown in the following code. The WindowsImpersonationContext class implements the IDisposable interface, and therefore the common language runtime (CLR) automatically reverts to the original identity once the code leaves the using block.
Dim identity = ServiceSecurityContext.Current.WindowsIdentity
Using identity.Impersonate()
' Run code under the caller's identity.
End Using
WindowsIdentity identity = ServiceSecurityContext.Current.WindowsIdentity;
using (identity.Impersonate())
{
// Run code under the caller's identity.
}
Impersonate Only as Needed
Using the Impersonate method of the WindowsIdentity class, it is possible to use impersonation in a very controlled scope. This is in contrast to using the Impersonation property of the OperationBehaviorAttribute, which allows impersonation for the scope of the entire operation. Whenever possible, control the scope of impersonation by using the more precise Impersonate method.
Obtain Metadata from Trusted Sources
Be sure you trust the source of your metadata and make sure that no one has tampered with the metadata. Metadata retrieved using the HTTP protocol is sent in clear text and can be tampered with. If the service uses the HttpsGetEnabled and HttpsGetUrl properties, use the URL supplied by the service creator to download the data using the HTTPS protocol.
Publish Metadata Using Security
To prevent tampering with a service's published metadata, secure the metadata exchange endpoint with transport or message-level security. For more information, see Publishing Metadata Endpoints and How to: Publish Metadata for a Service Using Code.
Ensure Use of Local Issuer
If an issuer address and binding are specified for a given binding, the local issuer is not used for endpoints that use that binding. Clients who expect to always use the local issuer should ensure that they do not use such a binding or that they modify the binding such that the issuer address is null.
SAML Token Size Quotas
When Security Assertions Markup Language (SAML) tokens are serialized in messages, either when they are issued by a Security Token Service (STS) or when clients present them to services as part of authentication, the maximum message size quota must be sufficiently large to accommodate the SAML token and the other message parts. In normal cases, the default message size quotas are sufficient. However, in cases where a SAML token is large because it contains hundreds of claims, the quotas should be increased to accommodate the serialized token. For more information about quotas, see Security Considerations for Data.
Set SecurityBindingElement.IncludeTimestamp to True on Custom Bindings
When you create a custom binding, you must set IncludeTimestamp to true. Otherwise, if IncludeTimestamp is set to false, and the client is using an asymmetric key-based token such as an X509 certificate, the message will not be signed.
See Also
Concepts
Security Considerations for Data
Security Considerations with Metadata