23 March, 2023
In today’s technology-driven world, security breaches and cyber attacks have become a common occurrence. The days of releasing a software product into the wild and addressing the security bugs with subsequent patches are (hopefully) over. Organizations are starting to realize that they need to focus on security in a systematic way during the software development lifecycle. Microsoft has created the first secure software development lifecycle (SSDLC) in the early 00s. SSDCL focuses on tackling security throughout each software development phase, rather than adding it as an afterthought.
Recently, I talked with Nikolay Dyakov, he is our most senior secure software engineer here at Codific. We talked about the secure software development lifecycle, why it is important and how to ensure that security is properly implemented into the secure software development lifecycle. Thus, based on what he told me and with my own research I wrote this blog post. Here you will learn everything you need to know about how to securely develop software!
Table of contents
- What is the secure software development lifecycle?
- Why is it important to integrate security into the software development lifecycle (SDLC)?
- What are the seven phases of the secure software development lifecycle?
- What are some common security vulnerabilities that developers should look out for during the software development process?
- How do you ensure that security requirements are met throughout the software development lifecycle?
- How can security testing be integrated into the software development process?
- How can code reviews and audits help improve the security of the software systems?
- What is DevOps and what additional practices should be integrated with the secure software development lifecycle?
- How do we manage our secure software development at Codific?
- What is the quickest way to improve my secure software development life cycle?
What is the secure software development lifecycle (SSDLC)?
Generally speaking, the Secure Software Development Lifecycle (SSDLC) is a structured approach that prioritizes security throughout the software development process to minimize vulnerabilities and reduce the risk of cyberattacks.
Accordingly, the SSDLC aims to reduce the risk of vulnerabilities and security weaknesses in software by integrating security practices during its design and development.
Why is it important to integrate security into the software development lifecycle (SDLC)?
According to a report released by Consortium for Information and Software Quality (CISQ) the cost of poor software quality in the United States was $2.4 trillion in 2022. One of the crucial areas that adds to this cost is cybercrime losses due to software vulnerabilities. These losses rose by 64% between 2020 and 2021 and by an additional 42% from 2021 to 2022. Moreover, the report also noted that cybercrime cost $7 trillion worldwide and that the average cost of a data breach in the United States amounted to $9.44 million.
Two other components that add to this $2.4 trillion are technical debt and software supply chain problems. Following a secure software development lifecycle could systematically tackle both issues. Technical debt refers to the cost of reworking software. Reducing software vulnerabilities from the start can help avoid the need for security patches, ultimately minimizing the need for rework. Software supply chain problems partially come due to weaknesses in open source components which increased by 650% between 2020 to 2021. Following the SSDLC could help improve the security and risk management of open source and non-open source components in your organization’s software products.
This is all to say that integrating security in the software development lifecycle is essential. It leads to security being a foundational aspect of the software development process. This is particularly relevant in today’s landscape, especially in the US and the EU, where regulations are being put in place that make software companies liable for any security flaws. Thus, not implementing security properly into your SDLC could lead to strong legal and monetary repercussions.
What are the seven phases of the secure software development lifecycle?
To help you understand how to implement the secure software development lifecycle it is important to comprehend the different phases of this process, these are:
Planning and Analysis
The planning and analysis phase of the SSDLC involves the creation of the functional and security requirements for the software. This should be done in collaboration with the different stakeholders, the development team and the project managers.
This requires an analysis of the feasibility of the project, identifying the potential threats and risks, and defining security controls. After completing the analysis in collaboration with different parties, generate a security and development plan and create a software requirements specification (SRS) document. This document guides the development team by defining product requirements and identifying technical approaches for successful project completion.
In the design phase of the SSDLC, the objective is to define a project design approach. Develop and document various design approaches in the design document specification (DDS), using the SRS document as the base. Review the DDS with stakeholders and choose the most viable software architecture based on parameters such as risk assessment, product robustness, budget and time constraints, and design modularity.
In the secure software development life cycle, the chosen design must include security controls and features, considering the security requirements specified in the planning phase.
The testing planning stage of the SSDLC involves the creation of a blueprint for the different tests that will be done to ensure that the software is working properly and is secure.
The test plan outlines:
- The testing strategy
- Testing resource requirements
- Testing environment
- Testing limitations
- Projected schedule for testing activities.
A quality assurance team usually executes this plan to ensure the quality of the final product.
In the SSDLC, it involves planning security tests, such as penetration tests and vulnerability scans, that need to be conducted.
This implementation stage of the SSDLC involves writing the code, following the design document specification (DDS). This emphasizes the importance of the design phase, as having a comprehensive and detailed DDS will help to streamline the coding process.
It is important that the developers follow the coding guidelines established by their organizations and by the program-specific tools they need to use, including the compilers, interpreters, and debuggers. Following the secure software development lifecycle framework requires that secure coding practices are employed.
This phase is usually done using different high-level programming languages like C, C++, Pascal, PHP, and Java. The chosen programming language will usually depend on the specific project.
The testing stage of the SSDLC entails the testing of the software to make sure all requirements in the SRS document are fulfilled, both in terms of functionality and security.
Notwithstanding, it is vital to emphasize that testing should be conducted throughout all phases of the SSDLC to ensure a sustainable and streamlined development process, although this stage primarily focuses on testing the program.
This stage involves the reporting, localization, fixing and retesting of the critical defects in the software for its deployment. In the secure software development lifecycle, this would also involve carrying out security tests like penetration and vulnerability tests.
The deployment stage of the SSDLC involves releasing the software into its intended environment/market.
Sometimes, this involves first deploying the software into a more limited sector of the market before testing it in the real business environment. On the other hand, some companies prefer to deploy it immediately to the real business environment to collect customer feedback which they can then use to continuously improve the product features and software usability.
Moreover, this stage requires the software to be properly configured and that all security controls are functioning properly.
The final stage of the SSDLC involves the ongoing maintenance of the software to ensure that it remains secure and continues to function properly over time.
From a security perspective, this entails monitoring for security vulnerabilities, patching vulnerabilities as they are discovered, and updating security controls as needed.
From a functional perspective, this entails patching any bugs that are affecting the usability of the software, releasing new updates with more product features and optimizing the current functionalities to improve them.
What are some common security vulnerabilities that developers should look out for during the software development process?
In this section we describe three of the most common security vulnerabilities that you should look out for when developing software. These are based on the OWASP Top 10 project, which is an industry benchmark for the most commonly occurring vulnerabilities in the wild.
There are two type of injection vulnerabilities often exploited in the wild, namely Cross Site Scripting (XSS) and SQL injections.
XSS vulnerabilities occur when an attacker is able to inject malicious code into a website, which is then executed by unsuspecting users. This can lead to data theft or unauthorized access to user accounts.
To protect against this you need to make sure that you block any executable code from any user input. Additionally, specific tips on how to do that can be found in the OWASP XSS Prevention Cheat Sheet.
An SQL injection attack consists of inserting an SQL query (a piece of code written in the structured query language) via the data inputted into the system. If the attack is successful the SQL injection can read sensitive data stored in the database, modify the database data, execute administrative operations on the database (such as shutting down the database management system (DBMS)), recover the content of a file present on the DBMS and in some cases issue commands to the operating system.
Protecting against this type of attack involves setting up security measures similar to those you would to protect against an XSS attack. Read more about SQL injections here.
2. Vulnerable and Outdated Components
Modern software is built on top of third party codebase, which is often over 80-90% of the overall code. Attackers can often quickly figure out what version of a component your software system is using. Moreover a library of readily available vulnerabilities and exploits for these components is at their finger tips. Hence, you need only basic tech skills to successfully exploit these systems. Protecting against these risks is simple: always update your software components to their latest versions. Unfortunately the reality is extremely messy as your components might have unpatched dependencies, backward compatibility issues or become abandoned just to name a few. Obviously to manage the third party components you first need to measure them by creating a Software Bill of Materials. Tools, such as Debricked are essential. The rest is black magic, but some good advice can be found in the Software Dependencies stream from SAMM.
3. Broken Access Control
These vulnerabilities occur when an attacker is able to bypass or exploit weaknesses in the authentication or authorization mechanisms of an application. This can lead to unauthorized access to sensitive data or systems.
A way to protect against authentication vulnerabilities is to use multi-factor authentication. To guard against authorization vulnerabilities, check the permissions of each request and establish authority rules that default to deny and only accept exceptions. In addition, more information about authorization vulnerabilities can be found on the OWASP Authorization Cheat Sheet.
How do you ensure that security requirements are met throughout the software development lifecycle?
Define security requirements
It is imperative that in the planning and analysis phase of the secure software development lifecycle you define secure requirements that are specific to the software being developed. This may require you to identify regulatory compliance requirements (e.g. GDPR compliance requirements), security best practices, and organizational policies that need to be followed. OWASP Application Security Verification Standard (ASVS) is the industry standard for security requirements and it is a great starting point for any software product.
Include security in the design phase
Security should be a key aspect of the design. This can involve developing threat models, identifying potential vulnerabilities, and designing security controls to deal with those vulnerabilities.
Threat modeling involves identifying and assessing potential threats to a software system, helping to develop strategies to mitigate those threats. You can learn more about how to carry out a threat model for your products in this blog post.
Moreover, we cover some of the common security vulnerabilities that you need to consider when following the SSDLC in this section.
Use secure coding practices
Developers should use secure coding practices. Some examples of these coding practices are:
- Input validation: Input validation is the process of checking the inputs to your software program and disallowing those which do not meet certain criteria. By only allowing inputs that meet specific criteria, this makes it much harder for an attacker to enter an input designed to harm a system. If you want to learn more about input validation then click here.
- Output encoding: This involves translating special characters into some different but equivalent form which is no longer dangerous in the target interpreter. This serves as a form of defense against cross-site scripting, a common vulnerability we cover in this section of the blog. You can learn more about output encoding here.
- Password hashing: This involves putting your password through a hashing algorithm to turn plaintext into an unintelligible series of numbers and letters. This makes it significantly more difficult to retrieve the password in the event of a security breach. You can learn more about it here.
Secure coding practices are part of the DevOps methodology which we cover in this section of the blog.
Conduct security testing throughout the development process to identify and address vulnerabilities, as previously mentioned. Later in this section of the blog, we cover how to implement security testing throughout the secure software development life cycle.
Monitor and address security issues
Once the software is released it is important to monitor for security issues, addressing any vulnerabilities identified. This can involve implementing security patches, conducting additional security testing, or making changes to the software architecture or design.
Periodic security audits
A security audit is a systematic evaluation that assesses an information system’s conformity to a set of criteria. Conduct periodic security audits to ensure that security requirements are met and the software is secure. You can do this by conducting internal audits with a dedicated security team or by hiring a third-party security audit. We cover security audits in this section.
Continuously improve security
Security requirements and best practices constantly evolve. It is important to continuously monitor and improve the security of the software throughout its lifecycle to ensure that it remains secure over time. For example, this would involve continuously testing the software for vulnerabilities and patching them with security patches. It is important to keep up with new developments in the field of software security to ensure that the latest information is considered when improving the software.
How can security testing be integrated into the software development process?
All phases of the secure software development lifecycle should integrate security testing security testing. There are various complementary approaches and techniques to do that.
Automated pipeline security testing
Automated pipeline security testing is the process of scanning the application for vulnerabilities using automated tools. These tools can be integrated into the build and deployment process (pipeline) to automatically test for common vulnerabilities. This approach can help identify security issues early in the development process, when they are easier to solve. Moreover, it can be particularly useful in identifying recurring issues. The following type of vulnerabilities are typically easily detected by the automated security testing tools:
- Injections: Such as XSS or an SQL injection.
- Buffer overflows: This occurs when a program attempts to put more data in a buffer (sequential section of memory allocation to contain data) that it can hold or when a program attempts to put data in a memory area past a buffer. Writing past the bound of the allocated memory can lead to data corruption, crashing of the program, or causing the execution of malicious code. You can learn more about buffer overflows in this OWASP article.
- Weak encryption algorithms: Using weak encryption algorithms can lead to sensitive data exposure, encryption key leakage, malfunctioning authentication, insecure sessions, and spoofing attacks (when an attacker impersonates an authorized device or user. MD5 and RC4 algorithms are examples of weak encryption algorithms. Learn more about this in this OWASP article.
Penetration testing is a testing method that involves attempting to breach some or all of a system’s security. Pen testing focuses on using the same tools and techniques that an attacker might use. Dedicated security testers or developers trained in security testing techniques can conduct these tests. This ultimately helps to identify security issues that automated tools may not detect.
Continuous integration and delivery pipelines
The DevOps practice of continuous integration and delivery (CI/CD) pipeline focuses on frequent and reliable software delivery.
This splits in two parts:
- Continuous integration: Continuous integration is a process through which developers can work independently on their own coding “branch” to implement small changes to the code. These changes are then pushed to an automated system that builds and tests the code changes before these are added into the master code.
- Continuous delivery: After the continuous integration process has finished, the code changes are put into a code repository. The operations team can then deploy them to a live production environment (where the latest version of the software is pushed live to the users). The software is then tested and errors are resolved through automated processes. After this, the DevOps team receives a notification about the latest build, which they can manually send to the deployment stage.
Integrate security testing into the CI/CD pipeline to identify and remediate security issues before releasing updates. Frequent code submissions can help solve security vulnerabilities in new code quickly, ensuring software quality. For more information on CI/CD pipelines, read here.
Additionally, this section of the blog explains the DevOps methodology and additional practices to consider.
Bug bounty programs
Bug bounty programs involve giving compensation to individuals for reporting bugs, especially those that relate to security issues. This helps to incentivize independent security researchers to identify and report security vulnerabilities in the software. Moreover, traditional security methods may not detect all vulnerabilities, this approach can help identify these additional vulnerabilities. As opposed to pen testing, bug bounty programs typically focus on actually exploiting the vulnerabilities.
How can code reviews and audits help improve the security of the software systems?
Code reviews and audits can help you improve the security of software systems in several ways.
Identify security vulnerabilities
Code reviews and audits can help you identify security vulnerabilities. These are vulnerabilities not easily detected by automated tools.
- Broken Access Control that is currently the most common vulnerability on the OWASP Top 10 list.
- Insecure Design that refers to a broad category of weaknesses expressed as “missing or ineffective control design”.
- Security Misconfiguration that represents a bunch of issues related to security hardening, unnecessary open ports and services, default accounts, etc.
Ensure compliance with coding standards
Code reviews and audits can ensure the code follows coding standards and secure coding practices like the ones covered previously. Ideally, every commit should be at least diagonally reviewed by a senior engineer. Commits related to security should get a more thorough review and enhanced by developing automated regression tests.
Improve software quality
By identifying and fixing defects early in the development process, code reviews and audits can help to improve overall quality of the software. This can reduce the risk of security vulnerabilities and improve the reliability of the software.
One of the most neglected issues out there is education. Security champions have a greater role in tackling the AppSec challenges, however security is everyone’s job in the organization. Every developer should have at least a get at least 50 hours of security training per year. Code reviews and audits could obviously help developers understand the problem and the gaps.
Provide feedback to developers
Finally, code reviews and audits provide feedback to software developers on their code. This can include suggestions for improvement and identification of potential security issues.
What is DevOps and what additional practices should be integrated with the secure software development lifecycle?
DevOps stands for development and operations; it is a methodology that allows organizations to deliver and improve software solutions efficiently. So far we have covered two DevOps practices that you should follow when implementing the secure software development lifecycle. These are continuous deployment and integration (CI/CD) and secure coding practices.
An additional DevOps practice you should implement is the use of containers. Containers are packages of your application and its dependencies. Isolating these containers from the host system and other containers can effectively reduce the risk of security vulnerabilities. In addition, more information on this can be found here.
How we manage our secure software development at Codific?
We develop applications in a wide range of verticals. Our product portfolio includes, amongst other things a secure video sharing application for medical education, HR-analytics tools, security posture management tools and a tool to monitor attendance at universities. The type of applications is very varied, but the one thing they all have in common is their focus on security. Thus, each one of our applications has explicit data security or privacy needs that are fundamental to the applications.
We have our own teams of secure software engineers that develop all of these applications. We never outsource development for our application but we do often use open source components. This has started our relationship with OWASP, the Open Web Application Security Project. OWASP is a non profit foundation defining, updating and championing the best practices in software security in an open world.
One flagship OWASP project we found super useful is the OWASP SAMM, the Software Assurance Maturity Models. It covers everything you need to keep track of as a company that makes software. We particularly appreciate how the different levels of maturity break down each activity. This allows you to target specific levels based on your risk profile and appetite. Moreover, you can do this on an activity basis based on the nature of the application.
So how do we use OWASP SAMM to manage our secure software development life cycle?
SAMM is an AppSec model, meaning that it is a more holistic model than the secure software development lifecycle framework as it also considers governance, education and strategy. Thus, following SAMM when trying to improve application security will also allow you to cover additional aspects that are not taken into account in the SSDLC. To manage our SSDLC with SAMM, we specifically look at the three central business functions of the model: Design, Implementation and Verification.
In the design function we follow everything we need to do when we are designing our application, from mapping out security requirements to threat modeling.
We think the implementation function is really important in securing the pipeline. Here we have automated a lot of the security controls with tools such as OWASP ZAP and Debricked. Recently, we wrote a guide on how to pick security tools for your DevSecOps.
We use the verification business function, to keep track of everything we need to check post deployment and on a regular basis, this includes penetration testing and our own Codific Secure Patrol that patrols our production servers with a combination of application level firewalls, behavioral analysis of traffic and some more fancy tricks we are not telling you :).
What is the quickest way to improve my secure software development life cycle?
We are such big fans of OWASP SAMM that we got actively involved as volunteers. Our team wrote a lot of the guidance you read in the model. Apart from that, the one big thing that was missing was a good tool to manage the process. Spreadsheets are not a good way to manage such processes across teams.
So we created that tool. It’s called SAMMY and it’s free to use.