Security in Remoting
This topic is specific to a legacy technology that is retained for backward compatibility with existing applications and is not recommended for new development. Distributed applications should now be developed using the Windows Communication Foundation (WCF).
As a developer of .NET remoting applications, you must have a good understanding of the security implications of not only .NET remoting, but of distributed applications in general. Without a secure implementation, anyone could call a method on your remote object or intercept confidential information as it is being sent to or from a remote object. To prevent this from happening you must authenticate clients (and possibly servers) and encrypt communication between the two.
There are less straight-forward issues as well. Consider a remote object that defines a method that takes a delegate as a parameter. A malicious developer could use the delegate to force the server application to run any code he or she wishes. When a delegate wraps a static method, any calls on that delegate are not remoted; the code is called in the application domain that invoked the delegate. For example, a rogue client may use this vulnerability by make a call to the remote object and passing a delegate that wraps a static method. The assembly that implements the static method can be copied to the server and when the delegate is invoked the static method would get executed on the server. To prevent this from happening you should always declare delegates used in remote objects with custom types and parameters that cannot be guessed by hackers. Additionally you should never allow a client to define and pass a type to your remote object that is to be deserialized.
This section describes the various approaches to security based on certain design decisions. Not all scenarios are addressed here, but these topics are a good starting point.
Code Access Security
Code access security is a mechanism that helps limit the access that code has to protected resources and operations. Normally when code attempts to access a protected resource, a stack walk is performed to ensure that all stack frames have permission to access the resource. When a call is made on a remote object, this stack walk is not performed across the remoting boundary. Therefore the remoting infrastructure requires FullTrust permission to execute on either the client or the server. FullTrust permissions essentially turns off Code Access Security. Any unauthorized use of a remoting application provides unauthorized access to FullTrust permissions.
Several system types extend MarshalByRefObject but also perform security checks at runtime to prevent anything outside the application domain from invoking an object of that type remotely. AppDomain and System.Windows.Forms.Form are two examples of such system types.
Security Considerations in Remoting Applications
In general, there are two areas of security that must be addressed in a distributed application: securing the communication channel and securing the application against improper use.
Securing the communication channel involves ensuring that messages are encrypted and that they are not modified in transit. Securing an application against improper use involves authenticating and authorizing callers. Authenticating a caller means to verify the caller is who they say they are. Authorizing a caller means to verify that the caller has the privileges required to make a certain call or access a protected resource.
The built-in channels support security as follows:
HttpChannel - Only supports authentication when remote objects are hosted by Internet Information Services (IIS). Encryption is only supported when IIS is configured to use SSL.
TcpChannel - Supports authentication and encryption.
IpcChannel - Supports authentication.
Authorization is something that you provide in your code. The built-in channels cannot provide this for you because they do not know what your code does and what restrictions you have imposed.
.NET Framework remoting does not do authentication or encryption by default. Therefore, it is recommended that you take all necessary steps to make certain of the identity of clients or servers before interacting with them remotely. Because .NET Framework remoting applications require FullTrust permissions to execute, if an unauthorized client were granted access on your server, the client could execute code as though it were fully trusted. Always authenticate clients and encrypt the communication streams.