CS.SV.EXPOSED_FIELD

Secured types should not expose fields.

If code has access to an instance of a type that is secured by a link demand, the code does not have to satisfy the link demand to access the type's fields.

Mitigation and prevention

To fix a violation of this rule, make the fields nonpublic and add public properties or methods that return the field data. LinkDemand security checks on types protect access to the type's properties and methods. However, code access security does not apply to fields.

Security training

Application security training materials provided by Secure Code Warrior.

Example 1

Copy
  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 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 library code that follows violates the rule.

Example 2

Copy
  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 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.

Example 3

Copy
  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());
         }
     }
 }

The application illustrates how, without permission to access a secured type's methods, code can access its fields.