CA2112: Secured types should not expose fields
TypeName | SecuredTypesShouldNotExposeFields |
CheckId | CA2112 |
Category | Microsoft.Security |
Breaking Change | Breaking |
A public or protected type contains public fields and is secured by a Link Demands.
The following example is composed of a library type (SecuredTypeWithFields) with unsecured fields, a type (Distributor) that can create instances of the library type and mistaken passes instances to types do not have permission to create them, and application code that can read an instance's fields even though it does not have the permission that secures the type.
The following library code violates the rule.
using System; using System.Reflection; using System.Security; using System.Security.Permissions; namespace SecurityRulesLibrary { // This code requires immediate callers to have full trust. [System.Security.Permissions.PermissionSetAttribute( System.Security.Permissions.SecurityAction.LinkDemand, Name="FullTrust")] public class SecuredTypeWithFields { // Even though the type is secured, these fields are not. // Violates rule: SecuredTypesShouldNotExposeFields. public double xValue; public double yValue; public SecuredTypeWithFields (double x, double y) { xValue = x; yValue = y; Console.WriteLine( "Creating an instance of SecuredTypeWithFields."); } public override string ToString() { return String.Format ( "SecuredTypeWithFields {0} {1}", xValue, yValue); } } }
The application cannot create an instance because of the link demand that protects the secured type. The following class enables the application to obtain an instance of the secured type.
using System; using System.Reflection; using System.Security; using System.Security.Permissions; // This assembly executes with full trust. namespace SecurityRulesLibrary { // This type creates and returns instances of the secured type. // The GetAnInstance method incorrectly gives the instance // to a type that does not have the link demanded permission. public class Distributor { static SecuredTypeWithFields s = new SecuredTypeWithFields(22,33); public static SecuredTypeWithFields GetAnInstance () { return s; } public static void DisplayCachedObject () { Console.WriteLine( "Cached Object fields: {0}, {1}", s.xValue , s.yValue); } } }
The following application illustrates how, without permission to access a secured type's methods, code can access its fields.
using System; using System.Security; using System.Security.Permissions; using SecurityRulesLibrary; // This code executes with partial trust. [assembly: System.Security.Permissions.PermissionSetAttribute( System.Security.Permissions.SecurityAction.RequestRefuse, Name = "FullTrust")] namespace TestSecurityExamples { public class TestLinkDemandOnField { [STAThread] public static void Main() { // Get an instance of the protected object. SecuredTypeWithFields secureType = Distributor.GetAnInstance(); // Even though this type does not have full trust, // it can directly access the secured type's fields. Console.WriteLine( "Secured type fields: {0}, {1}", secureType.xValue, secureType.yValue); Console.WriteLine("Changing secured type's field..."); secureType.xValue = 99; // Distributor must call ToString on the secured object. Distributor.DisplayCachedObject(); // If the following line is uncommented, a security // exception is thrown at JIT-compilation time because // of the link demand for full trust that protects // SecuredTypeWithFields.ToString(). // Console.WriteLine("Secured type {0}",secureType.ToString()); } } }
This example produces the following output.
Creating an instance of SecuredTypeWithFields. Secured type fields: 22, 33 Changing secured type's field... Cached Object fields: 99, 33