Strengthen Muscles of Software Systems
It is essential for software architects to ensure that the core of the software design is strong and maintained robust throughout the software lifecycle.
Join the DZone community and get the full member experience.Join For Free
While we understand the need for "Building Software Immunity" and the importance of "Secure Software Engineering Habits", it is equally essential for heavy lifters such as software architects, tech leads, or senior engineers to ensure that the core of the software i.e. architecture or design is strong and maintained robust throughout the lifecycle of the software. Strengthening muscles of software goes far into the software development process, deployment and operations. Typically, it can be achieved via embedding security in business requirements, following design principles, and secure design approaches.
Embedding Security in Requirements
Incorporating security concerns in the early phases of software development is far easier and cost-effective as many common pitfalls can be avoided that get harder to fix later. There are two approaches that can be taken while defining security requirements:
- Explicit security requirements:
- The user is authenticated and authorized to have an "Admin" role.
- Once the user is logged in, the user performs admin activities.
- Implicit security requirements:
- Authenticated and authorized user with the "Admin" role is allowed to perform admin activities.
Regardless of how it is worded, explicit security requirements require the identification and classification of security aspects in documentation and implementations. Whereas, implicit security requirements consider security as part of the business requirements. Depending on business needs, organization culture, practices, either of the approaches can be taken. It is much of a cultural aspect as it is a process or set of tools.
Guidelines and techniques such as The OWASP Application Security Verification Standard (ASVS) and OWASP SAMM Security Requirements can greatly benefit assessing and shaping such requirements during the designing process.
Software Design Principles
Software design principles and practices such as SOLID, Clean Architecture, and Domain-Driven Design are meant to produce high-quality software, however, these can also build a foundation for secure software. Such practices generate software programs that are understandable and maintainable while reducing technical debt. With a focus on design and domain, security becomes a natural part of business and hence software development processes.
The overwhelming problem with software development is that everything is part of the design process (Reeves, 1992).
Every line of code written by the developer constitutes towards designing the system in high-level programming languages such as Java, .NET, or python, etc. OO Fundamentals such as abstraction, data encapsulation define boundaries of object models, which in turn can help build software that is robust and difficult to break. Moreover, non-security expert developers write secure code naturally as a good design removes insecure constructs.
Take an example of Domain-Driven Design, which enforces stricter domain models. Domain experts and software programmers share a ubiquitous language that helps build domain objects closer to reality. As an example, data elements such as phone numbers aren't just a random sequence of characters. Instead, it can be designed to have its own data model with fixed length or even a fixed sequence of numbers. Enforcing such domain rules on the data objects (e.g. 10-digit numbers with area-specific rules) reduces chances of future flaws(aka bugs or defects) and avoids security vulnerabilities (such as CWE-20: Improper Input Validation or CWE-117: Improper Output Neutralization for Logs).
Choosing a robust framework for software applications is another consideration software architects, engineers have to make before major development starts. Many of these frameworks provide security-related features out of the box. For instance, the Spring framework in Java provides Cross-Site Request Forgery (CSRF) for Servlet Environments that are easily available and can be enforced in the applications.
Another example is a fail-fast technique, which stops a business flow within the system in case of an erroneous situation. It also prevents a bad actor from exploiting the system further, if failure is due to an intrusion attack.
These examples underscore the importance of following good software design fundamentals and practices in securing software under development.
Secure Design Practices
Robust software design practices can be best complemented by secure design practices that build and ensure security awareness in design, build, and deployment processes.
These include, but are not limited to, the following:
The importance of "Threat Modeling" in Application security can't be emphasized more. It is the first thing that comes to mind when we think of a secure design.
Anyone can learn to threat model, and what's more, everyone should. - Threat Modeling: Designing for Security by Adam Shostack
In a very minimal form, it involves stepping back from details and looking at software components at a higher level to find possible threats or security flaws. Various tools such as Threagile — Agile Threat Modeling Toolkit, Microsoft Threat Modeling, OWASP Threat Dragon can facilitate threat modeling during the design process. It is a useful tool to include in software design processes as many security flaws can be detected and mitigated before it's too late. An important aspect to remember here is Threat modeling is an iterative, continuous process that may take a long time to refine within teams and the process.
Supply Chain Security
Software supply chain attacks are common, however came in limelight after the SolarWinds Supply-Chain Attack. Although the source code was not compromised, the compromise of the build system resulted in a global hack. The executive order by the government underscores the seriousness and need for organizations to give "supply chain security"(Sec. 4. Enhancing Software Supply Chain Security) due diligence and care.
It highlighted the fact that automation, DevOps technologies in modern software build processes have widened the attack surface which needs immediate attention in software development processes. Software architects or engineers need to be aware of such threats and careful while choosing and maintaining CI, CD platforms. Security frameworks such as SLSA ("salsa") are helpful while determining security posture and preparing for protection.
CNCF paper emphasizes four key principles crucial to supply chain security:
- Every step in a supply chain should be “trustworthy”
- Automation is critical to supply chain security
- The build environments used in a supply chain should be clearly defined, with limited scope
- All entities operating in the supply chain environment must be required to mutually authenticate using hardened authentication mechanisms with regular key rotation.
Such frameworks and principles can define and guide us to manage software supply chains in a secure environment.
An extension of supply chain security is the consideration of runtime security. This can range from earlier web containers to modern containers such as docker. Teams can use SBOM (Software Bill Of Materials) before packaging applications into containers to ensure all components are secured. Tools such as Syft or Tern can help generate SBOMs for containers.
Another important characteristic of any software architecture is observability. Software architects have to ensure the software being built is observable during runtime for immediate detection or prevention of any potential attacks. Essentially, Security Observability requires software applications to provide three types of data, i.e. Logs, metrics, and distributed traces. Ensuring that software is built to generate required data securely is critical for Runtime security.
Building muscles into software applications to withstand potential attacks require deliberate attempts to exercise security (implicit and/or explicit) requirements, fundamental software design principles along with secure design activities that include threat modeling, securing the supply chain, and runtime of the software system. Various tools, frameworks, and techniques can make our approach easier and guided throughout the software development process.
Opinions expressed by DZone contributors are their own.