This is part 5 of the Getting into software architecture series. If you haven't read the first part, here it is: A primer for emerging software architects
For every software system, security is a continuous concern. As designers of software systems, we must ensure that components are not just high-performing and efficient, but also secure. This is where the concept of Security by Design comes in, a proactive approach that helps incorporate security into the architectural blueprint. With this method, potential threats can be proactively identified and addressed.
Let's explore the practices and principles of designing secure software architecture. We'll dig into how architects can spot and manage security risks early, secure coding practices, and the ongoing necessity of security testing and audits to maintain system integrity.
Identifying security risks
As a software architect, always remember to include security at every step. Whether you're an experienced software designer or just getting started, building secure, resilient software begins from the very first step.
When designing a software solution in an Agile environment, the design phase becomes more of a continually evolving entity, rather than a single static event. In Agile methodology, you prioritize iterative progress and ongoing refinement over a rigid step-by-step process. However, the principle of integrating security from the start remains unchanged, and becomes even more crucial.
Embrace the attacker's mindset
If you want to make your software secure, first, you need to think like a potential adversary. Identifying threats and vulnerabilities requires an understanding of what a cybercriminal might seek to exploit. This doesn't mean you have to put on a black hoodie and start planning heists, but rather, it asks you to proactively look for weak points in your software design that could be attractive to an attacker.
This practice involves probing your design and its components, assessing interfaces, data flow, access controls, and more. By exploring your system from an attacker's perspective, you can identify potential weak points and develop strategies to strengthen these areas before they become a liability. One possible path to learning more about this could be to attend a course in penetration testing.
Iterative risk assessments
In an Agile environment, ongoing, iterative risk assessments are important. The iterative nature of Agile calls for continuous integration and continuous delivery (CI/CD). As new functionalities are added, or when existing ones are tweaked, it's crucial to reassess security risks with each change. This ongoing cycle of risk identification and mitigation will help ensure that security remains a priority throughout the software development lifecycle.
For each identified risk, a mitigation strategy should be developed. This might involve adjusting design components, introducing additional security controls, or perhaps rethinking the way a particular functionality works. Each risk identified and addressed adds an extra layer of resilience to your software system.
But how do you get started with these risk assessments? Threat modeling is a strategy that prioritizes risks in order to guide the design of secure systems. It is a structured approach that helps you identify, quantify, and address the security risks associated with your software. It's a bit like drawing up a map of your software's security landscape.
Threat modeling involves several steps. First, you identify the key assets in your software that need protection – this could be anything from user data to proprietary algorithms. Next, you outline potential threats to these assets and detail the potential impacts in case these threats should materialize. The final step is to create controls to mitigate these threats.
In an Agile context, threat modeling isn't a one-off task done at the beginning of a project. Instead, it should be revisited regularly, especially when significant changes are made to the software architecture or functionalities. As new threats emerge and old ones evolve, your threat model should evolve too, reflecting the current risk landscape and ensuring that your defenses remain robust.
Threagile is an open-source toolkit that simplifies Agile Threat Modeling by allowing teams to model their architecture and its assets in a YAML file, automatically execute security checks, generate reports on potential risks with mitigation advice, and visually represent data-flow. It can be thought of as "Threat Modeling as Code", and it lets you store your models in Git for version control and continuous improvement.
Collaborate and communicate
Finally, security isn't a solitary pursuit – it is a team effort. Collaboration and communication are key in an Agile environment. Developers, architects, product owners, and others involved in the software development process should be engaged, also in the conversation around security.
Regular meetings could provide an opportunity to discuss potential risks, brainstorm mitigation strategies, and ensure that everyone is on the same page regarding security priorities. However, security should optimally be part of the daily conversation, and not a sporadic topic relegated to the occasional meeting.
By embracing an Agile approach to security, you can ensure that you're continually addressing potential vulnerabilities, adjusting to new threats, and strengthening our software's defenses. By considering security at every turn, you're building systems that are ready to stand up to the complex, evolving dangers of the digital world.
Secure coding practices
Developing secure code goes beyond just getting your software to work correctly. It's about ensuring that your code is resilient against potential security vulnerabilities. This begins with a mindset shift: every line of code you write, every function you develop, you need to consider its potential security implications.
In an Agile environment, where small chunks of functionality are developed, tested, and deployed rapidly, it's even more crucial to maintain a security-first approach. It's much easier and less stressful to catch and fix security issues in these smaller chunks than in a large codebase at the end of a long development cycle.
Coding standards and best practices
One way of improving our cybersecurity skill set is by following coding standards and best practices, which can help ensure you create safer and more secure software. Standards and best practices guide us around common mistakes and toward more secure software.
One important principle is Input Validation. The motivation for this is that you can never trust external input, from users or from other systems. As soon as some data arrives from outside of your system, it must be treated as if it could be malicious, either by mistake, by some technical error, or on purpose. Never pass input on to other components of your system before it has been checked and possibly cleaned. Following this principle ensures that only legitimate, anticipated data gets passed to your data storage, or sent back out to your end users. This can help you ward off a lot of different attacks, such as SQL injection or cross-site scripting. Don't forget that almost everything that your software handles is external data, including URLs, cookies, function calls and protocol headers.
Next there is the Principle of Least Privilege. In essence, this principle advocates that every software component and every user of the system should operate with the bare minimum privileges necessary to complete the task at hand. By confining access rights, you can significantly reduce the potential damage if unauthorized access occurs, or if a system component is exploited. For instance, if a user account is compromised, having only the most necessary access rights limits what an attacker can do. They can't access data or functions that are not within the user's permissions. This principle, when applied diligently to both user accounts and software parts, can significantly improve the overall security of your systems, making them more resilient to threats and attacks.
There are several other cybersecurity best practices worth noting. These include Regular Patching to keep all software components up to date, Encryption for sensitive data both in transit and at rest, Strong Authentication mechanisms such as multi-factor authentication, and Continuous Monitoring for potential security incidents. Each of these practices plays a vital role in creating a holistic resilient cybersecurity strategy. By following them, you can strengthen our digital defenses and make our software much less vulnerable to cyber threats.
In Agile methodology, regular code reviews play a critical role in maintaining the software's integrity. Code reviews are a bit like a buddy system, where peers can check each other's work, provide feedback, and catch any security issues that may have slipped under your radar.
Performing code reviews as a mandatory element of each pull request ensures that both quality and security remains a central focus throughout the development process. In these reviews, look for potential security issues like improper error handling, lack of input validation, and the use of deprecated or insecure APIs.
Collaborative security culture
Finally, remember that security is a team responsibility. It's not solely on the shoulders of a single developer or a security specialist. In an Agile team, collaboration and communication are key. Share security insights, discuss potential vulnerabilities, and brainstorm solutions together. A security-conscious team is a crucial ingredient in the recipe for resilient, secure software.
Establishing a set of common reusable components across an entire software organization can also significantly improve overall security. These shared elements, which may include APIs, libraries, and other key utilities, should be thoroughly vetted for security vulnerabilities and regularly updated to incorporate the latest security enhancements. By centrally managing and maintaining these components, organizations can ensure consistent implementation of security best practices, eliminate the repetition of common vulnerabilities, and streamline the application of security patches. In essence, this shared toolbox of components serves as a strong foundation, helping the organization to build more secure, reliable software systems while maintaining a uniform and high standard of cybersecurity.
Agile security testing
Once your software is deployed, regular security testing is important. With Agile's emphasis on frequent releases and continual updates, each modification to the software can potentially introduce new vulnerabilities. By implementing routine security testing, you can catch these issues early, remediate them promptly, and maintain our software's resilience.
How often should you conduct these security tests? Ideally, they should be integrated into the CI/CD pipeline, ensuring every update is checked for security. Furthermore, comprehensive security assessments should be conducted periodically based on your organization's policy or when significant changes are made to the application or its environment.
One important tool for security testing is penetration testing, often referred to as pen testing. It's like a friendly training match, where ethical hackers attempt to breach a software system, probing for weak points and potential vulnerabilities. In the Agile context, consider incorporating pen tests at significant milestones in your project, or after large chunks of functionality have been added. If your organization is on a large enterprise scale, and you apply the SAFe methodology, penetration testing could be performed at each Program Increment.
Pen testing offers a realistic perspective on the maturity of your system's security, providing insights into how an attacker might exploit your system and where your defenses could be improved. However, remember, the goal of pen testing is not to cause chaos but to gain insights. Always work with trusted professionals who will respect your system and its data.
Automated vulnerability scanning
As a complement to pen testing, vulnerability scanning provides a systematic, comprehensive sweep of your software for known vulnerabilities. These scans use automated tools to check your system against databases of known security issues. By incorporating these scans into your CI/CD pipeline, you can catch potential vulnerabilities as soon as they are introduced. Remember, these scans only check for known issues, so they should be used in combination with other testing methods for a more comprehensive security overview. One example of automated vulnerability scanning is Dependabot, which automatically scans GitHub repositories and creates pull requests to upgrade your dependencies whenever a vulnerability is discovered.
Another crucial tool is the security audit. Think of it as a thorough health check-up for your software's security, reviewing everything from coding practices to security policies and access controls, but also your organization's processes and routines for dealing with security incidents.
In Agile development, where changes are made frequently, it's beneficial to have these audits at regular intervals. This can help ensure that security best practices are being followed and that your security measures are keeping up with the changes in your software. An outside auditor can bring a fresh, unbiased perspective, while internal audits can help maintain ongoing awareness and accountability.
Embrace a combination of methods
Each of these testing methods offers unique insights, and together, they form a comprehensive security assessment. By integrating security testing and audits into your Agile processes, you maintain an ongoing awareness, enabling rapid response to emerging threats. Remember, security is not a one-off task but an ongoing commitment. We are not just writing software – we're creating a safer, more secure digital environment for everyone.
Continual learning and further reading
With evolving technologies and emerging threats, staying up-to-date with the latest security vulnerabilities and countermeasures is crucial. Subscribe to security-focused newsletters, join coding communities, or attend webinars. The more informed you are, the better equipped you'll be to write secure code.
Newsletters, Webinars and Podcasts
Articles in this series:
- A primer for emerging software architects
- Designing resilient software architecture
- Implementing software architecture patterns
- Simplicity in software architecture
- Designing software architecture for security (this part)
- Architectural documentation and communication
- Evolving legacy software architecture
- The role of software architects in Agile teams