With few exceptions, a design is produced for an application before development begins; for smaller projects, the programmers may produce the design, which may be closely related to the implementation and contain low-level technical details. Larger projects usually engage an application architect to produce a more abstract design, leaving development of it's components to individual development teams.
Security is an important part of the design process and cannot be left until the implementation phase. A fully integrated security policy will provide the greatest protection against your application being subverted and simplify the process of integrating security functionality into your code. You cannot retrofit a comprehensive security model into a design.
As the application designer, you need to have an understanding of the security capabilities provided by the platform that the application uses, in the same way that you must understand the features and functions of other components, such as databases and operating systems. This knowledge is important even if you will not be involved in the implementation of the application. Where possible we have written each chapter so that an explanation of the security features offered by .NET is separate from the details of how to apply the functionality during coding; we recommend that architects working at even the most abstract levels should read the latter material.
The first step towards applying security to an application design is to identify the restricted resources and secrets, two concepts that we introduced in Chapter 1. Recall that a restricted resource is functionality to which you wish to control access to, and a secret is some piece of data that you wish to hide from third parties.
4.1.1 Identifying Restricted Resources
Restricted resources tend to fall into three categories:
Creating the list of restricted resources associated with your application is the foundation for understanding the trust relationships that you need to define, which we discuss in the next section. We make the following suggestions to assist in developing your skills in identifying restricted resources:
4.1.2 Identifying Trust
Once you have identified the protected resources your application uses, you can define the trust levels your application will require of its users or clients to grant access to them. Trust can be granted to a wide range of entities, including users, code, external libraries, and different computers.
When you trust a user, you are granting the individual an ability represented by a restricted function resource. For example, if you were developing a banking application, you might allow loan officers to approve loan requests. .NET supports this approach with role-based security, where you define the types of user that will use the system, and consider which resources each requires to perform his work. We discuss .NET role-based security in Chapter 10.
If you grant trust to code, or to a class library, then you grant trust to the assembly that contains the classes; we introduced assemblies in Chapter 2. .NET uses attributes of the assembly (the strong name, the publisher, etc.), known as evidence, to grant trust to assemblies. We discuss evidence in Chapter 6, and its uses in Chapter 7, Chapter 8, and Chapter 9.
When you require trust, you are in effect asking to consume the restricted resources of another application. For example, if your application depends on access to a database, then you must ensure that the database server will accept connections from your computer, and that your application is able to read and write the data it needs. Trust is a chain of relationships that extends through the services on which your application depends, your application itself, and the services or users that make use of your application.
Identifying trust is the process of examining your restricted resources and establishing how access to them should be allocated. You should also examine how the services you depend on assign trust and ensure that your application design provides for complying with their trust demands. We make the following suggestions to assist in developing your skills in identifying trust:
4.1.3 Identifying Secrets
Identifying secrets is usually a simpler process than identifying restricted resources; you must examine each type of data that your application creates or processes, and decide if that data requires protection. In Part III, we discuss the measures that you can take to protect data, but we offer the following advice to assist you in ensuring that you correctly classify your application's data:
4.1.4 Failing Gracefully
You must accept that you cannot design or implement an application that is invulnerable to attack even the best security can be broken. As part of an application design, you should always specify what actions will be taken in the event of a security breach, and define a plan of action that ensures that your application fails gracefully, and does not expose other applications and services to subversion.
It is not acceptable to simply write security events to a log file and hope that someone acts on them. As the designer of the application, you have a responsibility to minimize the risk to which you expose your clients and customers. The details of the failure plan will differ based on the purpose and complexity of the application, but should include, at a minimum, details of how security breaches are to be dealt with and what immediate actions should be taken to protect your data and protected resources from further compromises.