Best Practices for Application Security
(Identity and Access Management)
How to manage fined-grain permissions in your business applications
This paper is dedicated to IT and Security professionals, in charge of designing or developing a new Access Control System for Business Applications.
It’s the result of 20 years of experience in application security.
It will guide you in the creation of an efficient and sustainable solution that will evolve with your various architectures and development technologies.
Why this paper ?
Identity and Access Management (IAM) solutions generally focus on identity management (user accounts) and coarse-grained permissions. They see applications as monolithic resources to which a user can, or not, access. This type of “all or nothing” control only protects the exterior of the application.
However, users do not have all the same access rights within a company. We need to go further, and define what users can do inside applications with fine grained permissions. This need is often covered by writing custom code in each application.
This document recommends best practices to manage fine grained permissions.
It aims to eliminate the following problems:
- Heavy development costs: the access logic is too complex and often redundant between multiple applications.
- A low level of security. Sensitive data and mission critical services are improperly protected:
- Impossible to update security within all applications at the same time, creating inconsistencies within company policy.
- Access rights become too complex or voluminous and administrators can no longer manage them correctly.
- Administrators are often unfamiliar with users and their roles (too far away or too many). The system does not allow for the delegation of rights administration to business managers who better understand user roles.
- Conflicts appear between security roles, generating security breaches. Administrators do not have the tools to allow them to efficiently detect and prevent security breaches.
- Loss in Agility: business initiatives are slowed by the spread of rules in all the applications. Each rule has to be transposed to a system in its adjoining application. Certain applications even impose a complete cycle of “develop, test and deploy” before being able to update security rules.
- Difficult (or impossible) controls: controllers lack visibility and cannot do a cross-sectional audit of all the applications. They need to negotiate with each team to obtain all the information - often incomplete or in different formats, making it difficult to analyse.
- Compliance is impossible: the problems listed above affect compliance with regulations such as Sarbanes-Oxley, HIPAA, GLBA or the European Data Protection Directive
This document looks at identity management and access control (IAM) inside applications. It contains recommendations for those in charge of conceiving access control systems, organizing access rights and administering applicative security on the long term.
This document does not look at access control outside of business software (for example, physical, system, and network security). Nor does it cover other risks related to applicative security (SQL Injection, network eavesdropping, cookie or HTTP header manipulation, denial of service...).
Remove application silos and unify access control
What’s a Silo?
Information systems are built over time, and often contain multiple independent applications. Each application includes its proper solution to manage fine-grained permissions, and sometimes its own user accounts thereby acting as an independent Silo.
Working with Silos
Working with Silos does not work:
- New rules do not apply in a coherent and simultaneous way in each system
- Administrative costs and the risk of error are high
- Controls are not exhaustive: difficult to obtain uniform information for all systems
Why don’t Silos work?
- The propagation of security rules is too complex: when a new rule is applied, all the applications cannot be modified in a coherent and simultaneous fashion because they rely on different security systems.
- Controls are not comprehensive; auditors are not autonomous and they need to ask each team information on their application. They are sometimes confronted with developers unlikely to answer their questions. Also, the transmitted information can be in different formats from one application to another, making it difficult for auditors to analyze and consolidate.
- Managing the security becomes expensive: the more heterogeneous and numerous the systems are, the more expensive they become.
- Certain organizations attempt integration solutions that are unable to resolve anything: connectors that allow the exchange of information on users and their access rights. But the synchronization of heterogeneous systems is very costly and lacks robustness. On top of that, the cost and risks of errors linked to the management of multiple security systems at the same time remains unchanged.
Expected benefits of a centralized access control:
- The implementation of a security rule would be immediately effective throughout all the secured systems. For example, if the sales team should no longer be able to view the addresses of employees, you should be able to withhold the functional permissions according to the group of users encompassing the sales team. This functional permission will immediately propagate via the technical actions predefined within each application (see above for functional permissions)
- Users accounts, their access rights and a history of operations performed would be centralized in independent storage. Auditors will be autonomous to control security in real time. They would have transversal visibility on all applications, without having to consolidate the data in different formats.
Centralized Access Control
- Each action done by the administrator update immediately and uniformly the security of all application in the company
- Administrative costs and risks are reduced
- Audits are easy, cross-cutting and control security in real time
- The administration tasks related to security, no longer being redundant between systems, would consume less resources and generate less errors.
Permission Based vs. Role Based Access Control
When discussing access control, the notion of Role Based Access Control (RBAC) arises often. The principal consists of attributing access rights based on the user’s role. Organizations thereby define user accounts and roles common to multiple applications, thereby deleting a part of the application silos.
In most cases, they will nevertheless leave each application to interpret the roles to define their own permissions. A part of the Silo remains concerned with the management of fine-grained permissions. Each application could therefore develop a specific access control logic and implement the security roles independently of other applications.
On the contrary, a Permission Based Access Control consists of standardizing fine-grained permissions for all applications. The management of permissions is thereby entrusted to the team in charge of access control, and outside the perimeter of the development team.
In this case, the permissions will be function type (see access right granularity). For example, an information system manages the business entity “client”. We define the permissions “CanViewClient”, “CanCreateClient”, “CanUpdateClient”... and we apply them to all the applications manipulated by the clients. This solution allows for the instant application of the same access control rules to all the applications, thereby eliminating the negative effects of application silos.
In this example, we test the role and then we must deduce and code several technical actions in the application.
//ex. An Application contains a role.
// 1. 'Sales Administrator'.
// which is responsible for performing view/add/edit/delete any sales related actions.
// and is restricted to few admin users only.
////This method checks if current logon user is a member of specified role.
bool isSalesAdmin = VGSecurityManager.Runtime.Roles.IsUserInRole("Sales Administrator");
//code actions for 'Sales Admin'.
//1. Enable 'Analyze Sales Report' functionality for current logon user.
btnViewSalesReport.Enabled = true;
//2. Enable 'Create Sales Order' functionality for current logon user.
btnCreateSalesOrders.Enabled = true;
//3. Enable 'Delete Sales Order' functionality for current logon user.
btnDeleteSalesOrders.Enabled = true;
//4. Enable 'Print Sales Order' functionality for current logon user.
btnPrintSalesOrders.Enabled = true;
In this example, we test the permissions and we have to deduce less technical actions directly related to the permission
//In case, you want more detailed, fine-grained security to specify for user,
//you can use permission based security.
//This method checks if current logon user contains specified permission.
//Can Create new sales orders
//Can Delete sales orders
//Can Print sales orders
Separate access logic from business logic
Fine-grained permissions should be externalized away from applications:
By taking the access control system out of the hands of application owners, development time and cost is significantly reduced (no security code needed in each application). Deploy a unified solution across several applications and heterogeneous IT stacks.
Access policies and applications usually have two very different lifecycles:
- New application version every few months
- Access policies evolving on a daily basis
Mixing access and business logic results in the following issues:
- Fixing security breaches takes too long (waiting for new versions of the application).
- Changing access policies is too expensive, as it implies a full development cycle.
2 possible options to externalize application permissions:
1. Dynamic permissions: Some tools can dynamically enable/disable application features, without changing the code. Developers don’t bother with security at all: it is managed after development by security staff, and enforced dynamically at run-time.
Dynamic Permissions: this example shows how to implement the new policy "Managers can read contracts", without writing security code or event anticipating security at development time.
2. Static permissions: Anticipate security by placing hooks in the application’s code. Leverage these hooks later to implement new security rules without touching the code.
Static permissions: this example adds the policy "Managers can read contracts", without changing or deploying the code again. Still, developers must anticipate by testing permissions in the application.
Static permissions :
//you can check permissions before enabling sensitive features.
//Enable/Disable feature - 'Open Contracts'
mnuViewContracts.Enabled = VGSecurityManager.Runtime.Principal.HasPermission("Can View Contracts");
//Enable/Disable feature - 'Edit Contracts'
btnEditContracts.Enabled = VGSecurityManager.Runtime.Principal.HasPermission("Can Edit Contracts");
Carefully choose the granularity of access rights
All permissions defined inside an application are considered as fine-grained permissions. Even so, there exist two types of application permissions, each having a different granularity and use.
Application-level: technical permissions
The permission is related to a physical element of an application: menu, button, list of data, fields, attributes, methods of a service, etc. Technical permissions are defined by developers, and are specific to an application, a website or a service.
- Granting/revoking 1 technical permission affects only 1 application
- Developers declare 1 permission for each item that must be secured (in the example above, a menu)
- Security administrators must know the application before they grant technical permissions to users
Code example for Technical permission:
//Permissions have been created to refer to each UI action.
//check if user has permission to use 'menu item' - 'Open Contract'
mnuViewContracts.Enabled = VGSecurityManager.Runtime.Principal.HasPermission("Can Use Menu Open Contract");
//check if user has permission to use 'button' - 'Export Contracts'
btnExportContracts.Enabled = VGSecurityManager.Runtime.Principal.HasPermission("Can Use Button Export Contracts");
//check if user has permission to use 'link button' - 'View Contracts List'
linkbtn_ViewContracts.Enabled = VGSecurityManager.Runtime.Principal.HasPermission("Can Use linkbutton View Contracts");
Enterprise-level: functional permissions
The permission is associated to an operation and a job entity (create an invoice, consult a contract…). Functional permissions can be common to multiple applications. They are defined by those specialized in the job and/or access control. Each development team then breaks down the functional permissions into technical actions. For example, the permission “CanViewContract” could act on forms, menus, buttons, etc. allowing to consult contracts in multiple applications.
Granting/revoking 1 functional permission instantly secures several applications:
- Security administrators declare a single - business oriented - permission
- Each development team transposes this permission into specific changes in their applications
- Security administrators do not need to know the applications when they grant functional permissions
Code example for functional permission:
//check if user has business oriented permission - 'Can View Contracts'
bool canViewContracts = VGSecurityManager.Runtime.Principal.HasPermission("Can View Contracts");
//Code at ‘APP#1’ by developers
//enable/disable link button ('Contracts List') based on permission 'Can View Contracts'.
linkbtn_ViewContracts.Enabled = canViewContracts;
//Code at ‘APP#2’ by developers
//enable/disable menuItem ('Open Contracts') based on permission 'Can View Contracts'.
mnuContract.Enabled = canViewContracts;
mnuViewContracts.Enabled = canViewContracts;
//Code at ‘APP#3’ by developers
//enable/disable button ('Export Contracts') based on permission 'Can View Contracts'.
groupbox_Contracts.Enabled = canViewContracts;
btnExportContracts.Enabled = canViewContracts;
Which option is best?
To begin with, it’s not recommended to combine the two types of permissions. This makes maintenance of the security more complex and increases the probability of conflicts between permissions as well as the creation of security flaws.
We will then choose one type of granularity in function of the needs of the organization:
Technical permissions can be suitable for simple cases, comprising a small volume of access rights. It’s why they are mainly used when access control is limited to a single application (application level security).
Functional permissions are recommended for larger more important volumes (enterprise level security). They let you raise access rights to the functional level, independent from the division of the information system of multiple applications.
Functional permissions offer the following benefits:
- They correspond to new management scenarios and rules, to which companies must constantly adapt. Translating permissions into technical actions will be treated ahead of time by developers, and will not hinder the business side of access control. Security rules remain coherent for the entire information system and easier to audit.
- They are also smaller in number than technical permissions. This point is fundamental in order to conserve control over security rules, a large volume being impossible to master by administrators (see “beware the volume)
- Daily administration of security is much more reactive: a single action by the administrator instantly secures all the applications. For example, we add the rule “The sales team can consult invoices”. We are giving the functional permission “CanViewInvoice” to the roles “Sales”. This rule is instantly propagated to the whole information system. No action is necessary from the developer’s side, all the applications understand the permission “CanViewInvoice” and are automatically secured.
Prefer to open doors, rather than to close them
There are two philosophies possible when defining access rights:
- Closing doors: By default, all the features are accessible. Restrictions are given to certain users, to limit their access to sensitive features.
- Opening doors: By default, no feature is accessible. Authorization is given to certain users for certain features.
On the other hand, a strategy based on opening doors offers a better level of security:
- Security vulnerability: The ‘opening doors’ strategy will limit weaknesses and will facilitate their detection: if the administrator forgets to authorize a feature, the user will not be able to use it and will immediately signal support. In contrast, if the administrator forgets to close a door, a user can access a sensitive feature and be a security risk. These vulnerabilities are difficult to detect, because the user does not realize or does not want to flag it. These breaches can then multiply and continue for a long time before IT teams detect them.
- Access rights conflicts: Access rights are in general regrouped into packets (roles or sets of permissions) before being assigned to a user. There often exists overlap between two packets (for example, when both control the same feature). This may cause conflicts, for example a packet authorizes access to a feature, whereas another restrains access - the result is therefore unpredictable and incoherent, and can create new security vulnerabilities.
Among all the possible combinations, only the authorization packets never create conflicts. In the worst case, you authorize access multiple times to the same feature, which has no impact on the security nor on the user experience.
- If the level of security required is low, with few permissions (a single application, for example) and they are mutually exclusive (no risk of conflict), you can user restrictions.
- In all other cases, and in particular if you are unsure about what needs may arise in the future, it is recommended to use an authorization system.
Minimize the volume of security data
When we create the foundation of a new system, we look at covering all the needs - present and future; this can make things very complex. Developers may focus on short term questions - the technical feasibility of the system - to the detriment of long term obstacles, such as the weight of administering a busy system.
That’s why the cost of administering a security system is often higher than creating it; the system manages a large volume of high-security rules and data, of which long term administration can be a real challenge. If control is lost, security vulnerabilities can appear.
How to avoid this problem?
- It’s impossible to avoid human intervention: this alone will allow you to analyze real life scenarios, make the right decisions and find the best compromise between security system and user productivity.
- We could lower the volume of security data without degrading the efficiency of the system. It’s the goal of the suggestions offered in this chapter.
- We could also distribute the data among multiple administrators, to reduce the volume managed by one person (see the chapter on administration delegation)
Simple is beautiful
Let’s take an easy example:
- A system composed of 10 applications (desktop, websites or web services)
- 100 forms or functions per applications
- 10 permissions by form, or function
The total number of permissions for this system would be 10*100*10 = 100,000. If the system has 1,000 users, the administrator needs to then supervise 100 million possible links between users and permissions! Difficult to imagine in a context where the list of permissions and users is constantly evolving.
Therefore, it’s critical to reduce the volume of information to monitor.
We could proceed in the following way:
- Group together access rights in coherent packets:
- Roles for simple cases
- Hierarchy of permission sets and roles for complex cases
- Group together users along their organizational criteria (for example, by department of by function). It is important that the hierarchy of the user groups reflects their real distribution within the company. The work related to attributing users into groups will be easier, thus reducing the risk of error and security vulnerabilities.
- Assign the access rights based on the roles of the group. The number of roles/groups will be much less numerous than the number of permissions/users, making it easier to manage and control.
- Allocate the users between different local administrators (see ‘Delegating administration operations’)
- Management of permissions will be easier to supervise
- Administration costs will be reduced
- Risk of losing control and security vulnerabilities are lowered
Delegate administration tasks
By allocating access control tasks between various persons (Distributed Administration Model), we optimize the productivity and quality of the administration:
- The workload having been distributed, the volume of information to manager per person is reduced, diminishing the risk of errors.
- We improve the quality of administration by leveraging the knowledge of each specific collaborator. For example, a Business Unit manager will be better placed to know the users, and the roles and rights they have within the organization.
Example of the distribution of administration tasks:
- Specification of access rights: Specialists of the function/job detail the access rights and group them into coherent packets.
- Enforcement of access rights: Developers transpose the access rights into technical actions, with the application: activate (or de-activate) the controls, filter the data, etc.
- Management of user accounts:
- The manager (department manager, site manager etc.) knows the needs of his users so he communicates the activation, deactivation or deletion of accounts to the apt administrator.
- In certain cases (a public website for example), the user can self-register. According to the security level requested, we can automatically give them the access rights by default, or let the administrator validate their account and give them access rights.
- For security reasons, the task of creation, modification, deletion of user accounts is given to a central authority in charge of the business directory (For example AD Administration)
- If the system anticipates the growth of user data (user profile), we can delegate this task to those best placed to address this: the users themselves or their managers.
- Assigning access rights:
- The assignment of access rights is given to the business manager, that knows each user well, their functions and their user rights.
- One principal must remain: a user cannot define their own rights. The business manager can give rights to his users, but cannot given them to himself. The role of administrator is given to him by a central authority in charge of applicative security.
Keep track of important operations
To satisfy the requirements of SOX, HIPPA and similar standards, you need to keep a log of operations completed by users and administrators. You also need to document in real time the users and their access rights.
In 2008, a large bank discovered the loss of 5 billion euros on its market activity. The management had to respond to the following questions: Who caused the loss? Who let him do it? And, are other traders able to do the same thing?
More generally, the norms require that the following 3 questions are covered:
- Who did what, at what date or over which period?
- Who gave the access rights, when and to whom?
- Who can do what today?
For the system to be efficient, the tracer and audit mechanisms have to be:
- Centralized and common to all applications
- Independent of the technology used by developers
- Accessible by all the applications (in order to trace operations in real time)
- Usable directly by all the controllers, who can audit the system at all moments, and without depending on the owner of each application.
Separate the security data of Development, Test and Production
Multiple distinct environments are generally necessary:
- When applications evolve, permissions do as well. Developers then have to update the existing permission sets. They do it in a development environment in order to not disturb the production.
- To err is human. Each oversight or incorrect manipulation can generate a security vulnerability. New permissions are therefore validated in a test environment, to reproduce the characteristics of production.
- After being validated, new permissions will be deployed into production. We can then insert new permissions without disturbing the security data already in production (existing user accounts and access rights)
- For security reasons, responsibilities must be split: the developer can modify permissions, but cannot deploy them into production. Only the exploitation manager can do this after validation from the testers.
Build a secure and evolutive infrastructure
Interdependence and scalability
The security system has to be independent of the technologies on which rely the applications (current and future). We can expose web services - consumed evenly by all the applications - to authenticate the users, load their permissions and trace their operations. A good documentation and a detailed API will facilitate an even implementation.
Scalability and flexibility
The security system should be modular, to adapt to all architectures and security rules of the company. According to the XACML standard (eXtensible Access Control Markup Language), an access control system should contain the following components:
- Policy Enforcement Point (PEP): The area where the user permissions are applied. For example, when the access rights require the restraint of certain features in the application. The PEP protects the secure application.
- Policy Decision Point: The heart of the security system. The PDP is the area where access requests are evaluated and compared to the user permissions and the security rules.
- Policy Information Point (PIP): A connector to the external information source (Active Directory, database…), that may be necessary to process certain access requests.
- Only accountants can create invoices
- John asks to create an invoice
- The PDP asks the PIP: Is John an accountant?
- Policy Retrieval Point (PRP): the component that stores the security data (database, folders…).
- Policy Administration Point (PAP): This is an administration tool. For example, the area where the permissions are edited and given to users.