Distrust and Verify Anyway
Security is based on establishing trust. Who should you trust? When should you trust them? How much should you trust them? Often, this “trust” conversation centers on a binary distinction between “trusted insiders” and “unknown outsiders”. However, even the “trusted insider” can betray trust, as evidenced in recent W-2 disclosure attacks.
There is a fundamental security principle to mitigate the risk of the “untrusted insider” called the “Principle of Least Privilege,” or assigning users the minimum number of privileges necessary for them to do their jobs and no more. While simple in theory, this is a very difficult principle to implement. In fact, as a web application penetration tester, one of the most common vulnerabilities that we identify is “missing or broken authorization,” or situations where the application trusted its users more than it should have.
Why is secure authorization so difficult to implement? After all, developers are generally familiar with how to authenticate users. In fact, whether a web application verifies user identities using passwords, retinal scans, or two-factor authentication, the development community has probably created a simple library to use. Implementing secure authorization, on the other hand, remains the responsibility for each development team, and not everyone understands the risks involved.
Whereas authentication relies on the user proving his/her identity, authorization relies on the application assigning the appropriate level of trust to an authenticated user. The most common method of assigning this trust is role-based trust, where each assigned role signifies a set of permitted, and forbidden, actions that the user can take, as well as permitted, and forbidden, data that the user can access. A user with a basic role in a blogging application, for example, might be allowed to read content, while a user with a writer role can create, edit, and delete his/her content as well.
While a motivated development team may still develop a library or framework for authorization, the complexity of permissions and roles for each application will only increase as websites grow in functionality and size. The imagined authorization library would still need to be securely configured to each application’s specific data, roles, and permissions. Instead of relying on external libraries and third party developers, each application team should ensure that they follow security best practices to prevent authorization vulnerabilities, both before and after deployment.
Define Security Requirements. Before any development occurs, the team should document what types of roles the application will manage and what the permissions of each role will be. This documentation should be easily accessible during the development process and the development team should refer to it early and often.
Put Security First. While it can be difficult to implement in a feature-first environment, all updates to functionality or user requirements during development should be weighed against the impact the update will have to the established security requirements. If the security requirements are changed midway through the project, formerly secure code, which followed the original requirements, may suddenly be vulnerable to vulnerabilities that would not have existed otherwise.
Security Code Testing. The development team should develop and perform thorough security tests, in the form of unit testing and static code analysis, to ensure that authorization issues do not arise, or are remediated, during testing. Detailed and current security requirements will help to ensure that these code tests are accurate and reflect up-to-date requirements.
Document Security Controls. It is easier for users to maintain secure best practices if they understand how the security controls work within the application. Ensure that security features and security assumptions are documented in a user-friendly format.
Penetration Testing. Vulnerability scanning and penetration tests help ensure that the security controls established are working as expected. Moreover, penetration testing takes a more holistic approach to security testing than individual unit tests and ensures that application elements are secure both on their own and in their integration with the rest of the application.
Publish Vulnerability Data. Critical security issues identified after deployment should be patched and updated promptly. Less critical issues can be deemed acceptable risks when weighed against the cost of applying patches. In either event, identified vulnerabilities within the application should be published so that clients/customers are aware and understand why they are applying security patches or what they need to do to further protect themselves if a particular patch is not developed. Always assume that the hackers know, or can identify, application vulnerabilities without any published data. Therefore, make it easy for clients and customers to defend themselves by providing them with the same vulnerability information.
Security is an ongoing process that requires regular check-ups and maintenance. Based on the effort involved, it can be easy to become discouraged and consider implementing best-practice security a losing battle. However, following simple security principles and making them a part of the work environment can help mitigate, if not eliminate, many major security risks. To mitigate the risks of broken or missing authorization, just remember the adage, “Distrust, and Verify Anyway”.