Security and serialization

Caution

Code Access Security (CAS) and Partially Trusted Code

The .NET Framework provides a mechanism for the enforcement of varying levels of trust on different code running in the same application called Code Access Security (CAS).

CAS is not supported in .NET Core, .NET 5, or later versions. CAS is not supported by versions of C# later than 7.0.

CAS in .NET Framework should not be used as a mechanism for enforcing security boundaries based on code origination or other identity aspects. CAS and Security-Transparent Code are not supported as a security boundary with partially trusted code, especially code of unknown origin. We advise against loading and executing code of unknown origins without putting alternative security measures in place. .NET Framework will not issue security patches for any elevation-of-privilege exploits that might be discovered against the CAS sandbox.

This policy applies to all versions of .NET Framework, but does not apply to the .NET Framework included in Silverlight.

Because serialization can allow other code to see or modify object instance data that would otherwise be inaccessible, a special permission is required of code performing serialization: SecurityPermission with the SerializationFormatter flag specified. Under default policy, this permission is not given to Internet-downloaded or intranet code; only code on the local computer is granted this permission.

Normally, all fields of an object instance are serialized, meaning that data is represented in the serialized data for the instance. It is possible for code that can interpret the format to determine what the data values are, independent of the accessibility of the member. Similarly, deserialization extracts data from the serialized representation and sets object state directly, again irrespective of accessibility rules.

Any object that could contain security-sensitive data should be made nonserializable, if possible. If it must be serializable, try to make specific fields that hold sensitive data nonserializable. If those fields cannot be made nonserializable, the sensitive data will be exposed to any code that has permission to serialize. Make sure that no malicious code can get this permission.

The ISerializable interface is intended for use only by the serialization infrastructure. However, if unprotected, it can potentially release sensitive information. If you provide custom serialization by implementing ISerializable, make sure you take the following precautions:

  • The GetObjectData method should be explicitly secured either by demanding the SecurityPermission with SerializationFormatter permission specified or by making sure that no sensitive information is released with the method output. For example:

    Public Overrides<SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter := True)>  _
    Sub GetObjectData(info As SerializationInfo, context As StreamingContext)
    End Sub
    
    [SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter
    =true)]
    public override void GetObjectData(SerializationInfo info,
    StreamingContext context)
    {
    }
    
  • The special constructor used for serialization should also perform thorough input validation and should be either protected or private to help protect against misuse by malicious code. It should enforce the same security checks and permissions required to obtain an instance of such a class by any other means, such as explicitly creating the class or indirectly creating it through some kind of factory.

See also