Discussions of security as it relates to applications often ends up polarizedeither focusing on specific coding issues or attacks on the underlying system used to gain access to or through the application. This article focuses on the importance of security during the architecture and design phases of an application, and provides an overview of the areas of security that need attention. Focusing on security early is one way to avoid weakness post-deployment, and to increase the overall strength and resilience of your applications.
The following three areas of security are important to analyze, one is obvious and the others perhaps not as obvious:
- Security functionality
- Security and usage
- Security and processing
When thinking of security in an application, it is easy to become focused on which security technologies and features are needed. These include user authentication, encryption of network and stored data, and access to that data by the aforementioned users, as well as the technologies used to provide them. This area of security functionality is more or less driven by the functional requirements for the application.
When applying security technologies, it is vital that they be used properly in accordance to best practices, such as how one manages keys in cryptographic systems, but also that their security is not negated by weaknesses elsewhere.
Everyone has heard the analogy of security being only as strong as the "weakest link in the chain." In practical terms, if one focuses only on security functionality and ignores security in the other areas of the application, there is practically a guarantee of weakness. Security needs to be thought of in a comprehensive manner and across layers, that looks beyond those specific security components and technologies; security isn't just a technology, but also a mode of operation and a process. Security is pervasive and is an important aspect of all functionality. It asks the questions of how? What? Where? And when?
- How do we expect people to use the application and how do we hope they will not use it?
- What kind of data, inputs, outputs, and interactions does it have and what happens if people do things we don't want?
- Where does it fit in relation to other systems, networks, and data, and where does my application increase risk to the user and cause exposure?
- When will defenses fall short, resulting in some form of compromise?
Before delving into the technical aspects, look at a simple analogya car. Each car has certain aspects of security functionality: the key, the lock, the seat belts, doors and windows, and alarm system. Do these things automatically make our vehicles secure? Unfortunately, they do not. If we fail to lock our cars, shut the windows, and set the alarm, or if we leave the key on the ground next to the door, the security has been compromised. To let the security functionality be effective, you must follow a process. This process includes what you should and should not do, with respect to the security of the car; for example, lock the door and set the alarm. It also includes the level to which improper action has been anticipated and defended against; for example, setting the alarm on a car also locks it. Consideration for security goes beyond the functional security components, and also looks at how people will use it and how it works together.
Designing applications therefore requires the same level of analysis. Merely providing security functionality does not mean that people will use it, or use it properly. It is also important to avoid "blue sky" modeling of applicationsthat is, an understanding of the application's functionality under only the ideal circumstancesno rain or clouds, but a world where it is always sunny. The extent to which you can anticipate and design for the inappropriate behaviors that your application and its users may attempt, the stronger the security of that application. So, when designing an application, it is important to go beyond the normal use cases that exemplify ideal behavior, but to also model scenarios that outline behavior of functionality for negative behavior. The area that naturally follows usage and anticipation of improper behavior is processing of data.
Processing of information refers to the internals of the application and how it uses, sends, and receives data among its own modules and to other applications and systems. Designing security into the processing aspects of an application means setting boundaries and defining reactions to undesired events. The extent to which the application designer understands the desired behaviors and constraints, the more secure the application will become. Some areas of processing that should be considered are:
- Access control
- Input validation
- Data protection
For the purposes of this article, consider the definition of authentication to be the process of identifying an entity, whether an object, system, user, or service. Many applications interact with other applications, libraries, and systems without any consideration for who or what they are, or whether they should be allowed to interact at all.
Most people probably think of users logging into a program when the term authentication is mentioned, but there are several other areas of authentication that need attention. When designing applications, the need for authentication should be considered at all borders, including:
- Intra-module identity: how you identify and authenticate other software modules to each other
- System identity: how you authenticate other systems and applications
- User identity: how you authenticate users
One basic form of authentication is the presentation of a name, token or keyas is often done with shared memory, or between modules. Identification in this case usually is a statically defined string within the code, and the authentication mechanism is merely taking that name, adding it to a list, and moving on, or perhaps a simple comparison to a list of accepted names. This may be sufficient, if the application and system is reasonably closed and has minimal to no interaction with outsiders. Most applications do not fall into this category, though; therefore, the method by which other entities gain an ability to interact with your application should be carefully chosen.
Access control refers to the right of an object to access another. It is commonplace to see many systems functioning as a unit. Take your typical web application: There is a Web server, often some external application that may provide dynamic page generation, such as PHP, and often a back-end database for storage. When implementing software that provides data from one point to another, the easy route is often taken; this allows access to any data via the API or network connection.
Should every person, application, and service have the same level of access to data and objects? Most likely, no. There are several standard models for access control that can be easily added to a system, and will increase the strength greatly. These include Role Based Access Control (RBAC), Lattice, Identity and Rule based access control, and others.
Access control should be thought of at multiple layers, from user interaction, all the way down through function and method calls. Applying access control to structures and objects in memory can greatly enhance the safety of an application by securing access to sensitive data, defining who or what is able to read and change those objects, and assuring state management.