Partial Trust Best Practices
This topic describes best practices when running Windows Communication Foundation (WCF) in a partial trust environment.
Apply the following practices when using the DataContractSerializer in a partially-trusted application.
All serializable types must be explicitly marked with the
[DataContract]attribute. The following techniques are not supported in a partial trust environment:
Marking classes to be serialized with the SerializableAttribute.
Implementing the ISerializable interface to allow a class to control its serialization process.
All types marked with the
[DataContract]attribute must be public. Non-public types cannot be serialized in a partial trust environment.
[DataContract]members in a serializable
[DataContract]type must be public. A type with a non-public
[DataMember]cannot be serialized in a partial trust environment.
Methods that handle serialization events (such as
OnDeserialized) must be declared as public. However, both explicit and implicit implementations of OnDeserialization are supported.
[DataContract]types implemented in assemblies marked with the AllowPartiallyTrustedCallersAttribute must not perform security-related actions in the type constructor, as the DataContractSerializer does not call the constructor of the newly-instantiated object during deserialization. Specifically, the following common security techniques must be avoided for
Attempting to restrict partial trust access by making the type's constructor internal or private.
Restricting access to the type by adding a
[LinkDemand]to the type's constructor.
Assuming that because the object has been successfully instantiated, any validation checks enforced by the constructor have passed successfully.
Using WCF from Fully-Trusted Platform Code that Allows Calls from Partially Trusted Callers
The WCF partial trust security model assumes that any caller of a WCF public method or property is running in the code access security (CAS) context of the hosting application. WCF also assumes that only one application security context exists for each AppDomain, and that this context is established at AppDomain creation time by a trusted host (for example, by a call to CreateDomain or by the ASP.NET Application Manager).
This security model applies to user-written applications that cannot assert additional CAS permissions, such as user code running in a Medium Trust ASP.NET application. However, fully-trusted platform code (for example, a third-party assembly that is installed in the global assembly cache and accepts calls from partially-trusted code) must take explicit care when calling into WCF on behalf of a partially-trusted application to avoid introducing application-level security vulnerabilities.
Full-trust code should avoid altering the CAS permission set of the current thread (by calling Assert, PermitOnly, or Deny) prior to calling WCF APIs on behalf of partially-trusted code. Asserting, denying, or otherwise creating a thread-specific permission context that is independent of the application-level security context can result in unexpected behavior. Depending on the application, this behavior may result in application-level security vulnerabilities.
Code that calls into WCF using a thread-specific permission context must be prepared to handle the following situations that may arise:
The thread-specific security context may not be maintained for the duration of the operation, which results in potential security exceptions.
Internal WCF code as well as any user-provided callbacks may run in a different security context than the one under which the call was originally initiated. These contexts include:
The application permission context.
Any thread-specific permission context previously created by other user threads used to call into WCF during the lifetime of the currently running AppDomain.
- The application permission context.
WCF guarantees that partially-trusted code cannot obtain full-trust permissions unless such permissions are asserted by a fully-trusted component prior to calling into WCF public APIs. However, it does not guarantee that the effects of asserting full trust is isolated to a particular thread, operation, or user action.
As a best practice, avoid creating thread-specific permission context by calling Assert, PermitOnly, or Deny. Instead, grant or deny the privilege to the application itself, so that no Assert, Deny, or PermitOnly is required.