Implementing Security Access Control (SAC)
Security access control (SAC) is an important aspect of any system. Security access control is the act of ensuring that an authenticated user accesses only what they are authorized to and no more. The bad news is that security is rarely at the top of people’s lists, although mention terms such as data confidentiality, sensitivity, and ownership and they quickly become interested. The good news is that there is a wide range of techniques that you can apply to help secure access to your system. The bad news is that as Mitnick and Simon (2002) point out “”¦the human factor is the weakest link. Security is too often merely an illusion, an illusion sometimes made even worse when gullibility, naivette, or ignorance come into play.” The go on to say that “security is not a technology problem – it’s a people and management problem.” Having said that, my experience is that the “technology factor” and the “people factor” go hand in hand; you need to address both issues to succeed.
This article overviews the issues associated with security access control within your system. Although it includes a brief discussion of authentication, the primary focus is on authorization, assuring that users have access to the functionality and information that they require and no more. The issues surrounding authorization are explored in detail as well as both database and object-oriented implementation strategies. As with other critical implementation issues, such as referential integrity and concurrency control, it isn’t a black and white world. A “pure object” approach will likely prove to be insufficient as will a “pure database” approach, instead you will need to mix and match techniques to find a fit-for-purpose strategy.
Table of Contents
- Effective Security Strategies
Authentication is the act of determining the identity of a user and of the host that they are using. The goal of authentication is to first verify that the user, either a person or system, which is attempting to interact with your system is allowed to do so. The second goal of authentication is to gather information regarding the way that the user is accessing your system. For example, a stock broker should not be able to make financial transactions during off hours from an Internet cafÃ, although they should be able to do so from their secured workstation at their office. Therefore gathering basic host information, such as its location and security aspects of its connection (is it encrypted, is it via a physical line, is the connection private, …), is critical.
There are several strategies that you can follow to identify a client:
- User id and password. This is the most common, and typically the simplest, approach to identifying someone because it is fully software-based.
- Physical security device. A physical device, such as a bank card, a smart card, or a computer chip (such as the “Speed Pass” key chains used by gas stations) is used to identify a person. Sometimes a password or personal identification number (PIN) is also required to ensure that it is the right person.
- Biometric identification. Biometrics is the science of identifying someone from physical characteristics. This includes technologies such as voice verification, a retinal scan, palm identification, and thumbprints.
Authorization is the act of determining the level of access that an authorized user has to behavior and data. This section explores the issues surrounding authorization, there is often more to it than meets the eye, and then explores various database and object-oriented implementation strategies and their implications.
Fundamentally, to set an effective approach to authorization the first question that you need to address is “what will we control access to?” My experience is that you can secure access to both data and functionality, such as access to quarterly sales figures and the ability to fire another employee respectively. Your stakeholder’s requirements will drive the answer to this question. However, the granularity of access, and your ability to implement it effectively, is a significant constraint. For example, although you may be asked to control access to specific columns of specific rows within a database based on complex business rules you may not be able to implement this in a cost effective manner that also conforms to performance constraints.
The second question that you need to answer is “what rules are applicable?” The answer to this question is also driven by your stakeholder’s requirements, although you may need to explore various security factors that they may not be aware of (they’re not security experts after all). These factors, which are often combined, include:
- Connection type
- Update access
- Time of day
- Cascading authorization
- Global permissions
- Combination of privileges
Let’s start by reviewing the concepts of roles and security contexts. A role is a named collection of privileges (permissions) that can be associated to a user. So, instead of managing the authorization rights of each individual user you instead define roles such as HR_Manager, HR_User, Manufacturing_Engineer, Accountant, and so on and define what each role can access. You then assign users to the roles, so Sally Jones and her co-workers would be associated with the role of Manufacturing_Engineer. Someone else could be assigned the roles of HR_Manager and HR_User if appropriate. The use of roles is a generic concept that is used by a wide range of technologies, not just databases, to simplify the security administration effort.
A security context is the collection of roles that a user is associated with. The security context is often defined as part of the authentication process. Depending on the technology used a security context is maintained by the system, this is very common in GUI applications, or must be passed around by the system, something that is common with browser-based n-tier system. A combination of the two strategies is also common.
Authorization can be enforced within your database by a variety of means (which can be combined). These techniques include:
- Permissions. A permission is a privilege, or authorization right, that a user or role has regarding an element (such as a column, table, or even the database itself). A permission defines the type of access that that is permitted, such as the ability to update a table or to run a stored procedure. In SQL, permissions are given via the GRANT command and removed via the REVOKE command. When a user attempts to interact with a database his or her permissions are checked, and if the user is not authorized to perform part of the interaction, which could be a transaction, the interaction fails and an error is returned.
- Views. You can control, often to a very fine level, the data that a user can access via the use of views. This is a two-step process. First, you define views that restrict the tables, columns, and rows within the tables that a role can access. Second, you define permissions on those views.
- Stored procedures. Code within the stored procedure can be written to programmatically check security access rules.
- Proprietary approaches. A new option being offered by some database vendors is proprietary security tools.
The primary goal of database security is to ensure that there isn’t any “backdoor” ways to access critical corporate data. Many organizations choose to disallow ad-hoc queries to production databases to help minimize the chance of unauthorized access (as well as to avoid the associated performance problems). Many organizations introduce reporting databases such as data marts to support ad-hoc queries.
Because objects encapsulate both data and behavior an object-oriented (OO) authorization strategy needs to include the ability to secure both. This can be problematic because common object-oriented programming languages (OOPLs) such as Java, C#, C++, and Visual Basic do not natively include security features. Instead you must set a strategy, perhaps a combination of the ones listed below, and then follow that strategy. The implication is that you need to verify, through testing and inspections, that your organizational security strategy is being followed.
Yoder and Barcalow (2000) have developed a pattern language for enabling application security. These patterns are:
- Check Point. This is the place to validate users and to make appropriate decisions when dealing with security breaches. Also known as Access Verification, Validation and Penalization, and Holding off Hackers.
- Full View With Errors. Users are presented with all functionality, but when they attempt to use functionality that they are not authorized to use, an appropriate error-handling procedure is followed. The advantage is that this approach is easy to implement, but it puts you at risk because it reveals functionality to people that they may then decide to try and gain unauthorized access to.
- Limited View. Users are presented with what they are allowed to run. This approach is generally harder to implement but is considered user-friendly and more secure than a Full View with Errors approach.
- Roles. Users should be assigned to one or more roles, such as HR_Manager, and security rules should be defined in terms of those roles.
- Secure Access Layer. An application is only as secure as its components and interactions with them, therefore you need a secure access layer (or framework) for communicating with external systems in a secure manner. Furthermore, all components of an application should provide a secure way to interact with them.
- Session. Captures basic authentication information (ID and host) as well as the user’s security privileges. Also known as Session Context or Security Context.
- Single Access Point. Entry into a system should be through a single point. It should not be possible to get into a system via a back door. Also known as Login Window, Guard Door, and One Way In.
Although these patterns are straightforward, which is a very good thing, the interesting ones are the two that deal with user interface (UI) issues – Full View With Errors and Limited View. These patterns address the existence issue discussed earlier and commingle it with usability issues.
Authorization can be implemented with your objects following a variety of strategies. These strategies include:
- Brute force. Any operation that requires authorization must implement all of the logic itself.
- Business rules engine. Authorization logic is passed via invocations to a business rules engine. Each operation that requires authorization simply needs to invoke the appropriate rule(s) in the business engine and act accordingly.
- Permissions. This is the same strategy as using permissions within a database, the only difference is that permissions are applied to the operations of classes instead of to database elements. This approach is taken by Enterprise JavaBean (EJB) servers, where the EJB container automatically compares the access rights of an operation with that of the user invoking it. When no permissions are set, the container will still check the defaults and perform the same type of check.
- Security framework/component. Authorization functionality is encapsulated within a security framework. Security frameworks/components can be deployed to client, application server, or even database server machines.
- Security server. A specialized, external server(s) implements the security access control rules that are invoked as required.
- Aspect-oriented programming (AOP). Aspect-oriented software development is an emerging collection of technologies and techniques for separation of concerns in software development. The techniques of AOSD make it possible to modularize crosscutting aspects of a system. A good resource is the Aspect Oriented Software Development home page.
In the previous sections you have seen that you have several technical alternatives for implementing authorization rules. You have also seen that each alternative has its strengths and weaknesses. Similar to those concerning referential integrity, there are some important implications for agile software developers:
- Recognize that it isn’t a black and white decision
- Implement security access control on commonly shared tier(s)
- Be prepared to combine strategies
- Be prepared to implement security access control logic in several places
- Keep performance in mind
- Take advantage of existing database authorization practices
- Be prepared to evolve your strategy over time
I’d like to share a few words of advice that have worked well for me over the years:
- Base your security approach on actual requirements.
- Strive for an enterprise security strategy, but be realistic.
- Don’t overdo security
- No security approach is foolproof
- Give people only the access that they need
- Limit permissions to a small set of hosts
- Remember performance
- Don’t forget other security issues such as audit control and logging
- Adopt industry standards