.NET Framework 1.1 Security Guidelines - Class Design Considerations

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Alex Mackman, Michael Dunner, Srinath Vasireddy, Ray Escamilla and Anandha Murukan


Contents

Restrict Class and Member Visibility

Use the public access modifier only for types and members that form part of the assembly's public interface. This immediately reduces the attack surface because only public types are accessible by code outside the assembly. All other types and members should be as restricted as possible. Use the private access modifier wherever possible. Use protected only if the member should be accessible to derived classes and use internal only if the member should be accessible to other classes in the same assembly.

Note C# also allows you to combine protected and internal to create a protected internal member to limit access to the current assembly or derived types.


Seal Non-Base Classes Where Appropriate

By default types should be unsealed. You should seal non-base classes to prevent inheritance if either of the following conditions is true:

* If the class contains security secrets like passwords, accessible through protected APIs. * If the class contains many virtual members that cannot be sealed and the type is not really designed for third-party extensibility.

You prevent inheritance by using the sealed keyword as shown in the following code sample.

public sealed class NobodyDerivesFromMe
{}

Note In Microsoft Visual Basic .NET, you can use the NotInheritable keyword at the class level, or NotOverridable at the method level.

For base classes, you can restrict which other code is allowed to derive from your class by using code access security inheritance demands. For more information, see "Authorizing Code" in Chapter 8, "Code Access Security in Practice." at http://msdn.microsoft.com/library/en-us/dnnetsec/html/THCMCh08.asp


Restrict Which Users Can Call Your Code

Annotate classes and methods with declarative principal permission demands to control which users can call your classes and class members. In the following example, only members of the specified Windows group can access the Orders class. A class level attribute like this applies to all class members. Declarative principal permission demands can also be used on individual methods. Method level attributes override class level attributes.

[PrincipalPermission(SecurityAction.Demand,
                    Role=@"DomainName\WindowsGroup")]
public sealed class Orders()
{
}

Also, you can strong name your assembly to ensure that partially trusted callers cannot call into it.


Expose Fields Using Properties

Make all fields private. To make a field value accessible to external types, use a read only or a read/write property. Properties allow you to add additional constraints, such as input validation or permission demands, as shown in the following code sample.

public sealed class MyClass
{
 private string field; // field is private
 // Only members of the specified group are able to
 // access this public property
 [PrincipalPermission(SecurityAction.Demand,
         Role=@"DomainName\WindowsGroup")]
 public string Field
 {
   get {
       return field;
   }
 }
}
Personal tools