Designing Secure Applications
Modern applications are exposed to constant security threats. Malicious actors will try to uncover and exploit any vulnerabilities to steal private data, disrupt your service, and more. When designing our applications, we must prevent or mitigate these potential vulnerabilities as early as possible. Identifying and fixing security gaps late in the development process can be very expensive. Many of the biggest vulnerabilities arise from poor design and require significant effort to fix. You can avoid wasting time and resources by following the right principles in the application design phase.
Follow these principles to ensure your application is ready to meet rigorous security demands.
Confidentiality: Only authorized people (or processes) can get access.
Integrity: The presented data is unaltered.
Availability: The system and its data are available even under adverse circumstances.
Authenticity: Users are who they claim to be.
These security criteria should be something that becomes embedded into the operation of the company and not just security guidelines that come when code is written. This needs to form part of the functional requirements of the software and how things get designed from the very beginning. If requirements do not cater for a functional way of how confidentiality will be handled across every part of a software system, then even developers coding in a very secure manner is unlikely to resolve the issues.
Before we get into the different principles that need to be followed, it's important to get your processes aligned and ensure that your business, architecture, developers, and other stakeholders are all aligned in ensuring that secure design is not compromised at any point of the development journey.
Developing use/misuse cases
Work with the architecture group to model use and misuse cases. While use cases depict the application's functionality, the inverse of the use cases (misuse cases) is modeled to understand and address the software design's security aspects. These are known things in the way software can be misused to expose or exploit vulnerabilities. These misuse cases should be turned into standard case templates that can be used to form the basis of security testing and security scans and ensure that the software requirements take all these cases into consideration.
Performing software security design and architecture reviews
The security architect should get involved when the teams are engaged in the functional design and architecture review of the software. To ease this process, try using the checklist approach since that works great and can be tracked. It is imperative that the architects in charge of security work closely with the architecture team to generate a software security plan which outlines its design in detail. The same can be used as a check-and-balance guide during and after development.
Performing threat and risk modeling
Threat modeling helps in determining the software's attack surface by examining its functionality for trust boundaries, entry points, data flows, and exit points. If you are not familiar with the technique, use a threat modeling tool, because it always comes in handy for this exercise. The next activity that follows is risk modeling of software. It is accomplished by ranking the threats as they pertain to the organization's business objectives, compliance and regulatory requirements, and security exposures.
These can be rather lengthy processes for companies to perform and may come with measures that could easily frustrate many of the development teams as certain restrictions may seemingly take their freedom away. However, when you consider the costs that security vulnerabilities cost a company, its reputation, and importantly, its customers, then it should be seen as a necessity despite the potential disruption.
Least Privilege Design Principle
The general rule behind this principle is to provide the least amount of access privileges that any individual needs. Often, in an effort to become more efficient, companies tend to give people too much access to allow them to do their jobs.
The implications of granting access beyond this scope will allow for unnecessary access and the potential for data to be updated out of the approved context. The assigning of access rights will limit system-damaging attacks from users whether they are intentional or not.
This principle attempts to limit data changes and prevents potential damage from occurring by accident or error by reducing the number of potential interactions with a resource.
This is not just true for human users but also system generated accounts. System accounts that the software will use to interact with various other components or infrastructure in a system should only have the access to interact with the systems it needs and perform the tasks required. This way, even if the code does something unintended or it gets compromised in some way, there is a limit to how much it can damage the rest of the system.
Fail-Safe Defaults Design Principle
This principle goes hand-in-hand with the principle of least privilege. The Fail-Safe Defaults design principle pertains to allowing access to resources based on granted access over access exclusion. This means that any access is granted only if explicitly needed and that by default, users do not have access to any resources until the access has been granted.
This prevents unauthorized users from gaining access to any resources unless explicitly authorized to do so.
Economy of Mechanism Design Principle
You are probably picking up a trend around the concept of simplicity in many of the design aspects in this book, but it just goes to show how important simplicity is to building a safe and secure software system.
The Economy of Mechanism design principle requires that systems should be designed as simple and small as possible. As we’ve already learned, simple code is easy to test and this applies to security as well, as the different security scanning and security tests will be easier to write if the code is small and uncomplex.
Added complexity increases the likelihood of testing scenarios being missed and also certain faults in the code going unnoticed.
Open Design Principle
The Open Design Principle is the concept that the security of a system and its algorithms should not be dependent on the secrecy of its design or implementation.
This is an important principle for the open-source movement that the software world is currently in. While companies want to protect their intellectual property and may want to therefore not provide others access to their code, the reason should never be for security reasons. If there is an aspect of your code that you feel exposes your security in any way, then it probably should be redesigned.
Putting scanning software in place should help to identify any issues like this in the code, but it also requires a bigger look at how systems interact with the code and for teams to actively review the code and test for these areas.
Separation Privilege Design Principle
The separation privilege design principle requires that all resource-approved resource access attempts be granted based on more than a single condition. For example, a user should be validated for active status and has access to a specific resource.
Doing this sounds like an extra system administration overhead as it makes access more difficult, but this added measure can provide a lot of additional protection to ensure any users or resources do not behave in unexpected ways.
Least Common Mechanism Design Principle
The Least Common Mechanism design principle declares that mechanisms used to access resources should not be shared. So this is another principle that requires additional overhead and works to develop more mechanisms that handle the different permissions management and access of resources but separating these areas, it reduces the risk should any system become compromised or perform incorrectly in any way.
Defense in Depth Design Principle
The Defense in Depth design principle is a concept of layering resource access authorization verification in a system to reduce the chance of a successful attack. This layered approach to resource authorization required unauthorized users to circumvent each authorization attempt to gain access to a resource.
When designing a system that requires meeting a security quality attribute architects need to consider the scope of security needs and the minimum required security qualities.
Not every system will need to use all of the basic security design principles but will use one or more in combination based on its threshold for system security because the existence of security in an application adds an additional layer to the overall system and can affect performance.
That is why the definition of minimum security acceptably is needed when a system is designed because this quality attribute needs to be factored in with the other system quality attributes so that the system in question adheres to all qualities based on the priorities of the qualities.