- COMP.SEC.100
- 18. Secure Software Lifecycle
- 18.1 Secure software development
Secure software development¶
In the previous module, software vulnerabilities and methods for avoiding them were discussed. Securing software is not necessarily inexpensive, and especially in the early days of the Internet organisations often directed resources towards protecting network connections while trying to save costs by securing software only reactively, that is, by fixing vulnerabilities only after they had been discovered. The “penetrate and patch” approach has its disadvantages:
- It can be costly. According to an IBM-sponsored study, in 2025 the average cost of a single data breach worldwide was USD 4.4 million, and USD 10.2 million in the United States (the study covered 600 organisations). In addition, breaches cause reputational damage that is difficult to quantify.
- Attackers may remain undetected for long periods. According to the same study, detecting the exploitation of a vulnerability took an average of 181 days, and remediation took 60 days.
- Fixes may introduce new vulnerabilities.
- Updates are often not installed. For example, the Heartbleed vulnerability was discovered in 2014, but in 2017 there were still 200,000 vulnerable devices connected to the Internet.
In its historical overview, CyBOK suggests that this change began as late as 1998 with Gary McGraw’s short article: Testing for security during development: **why we should scrap penetrate-and-patch**. A few more years still passed:
Secure software development model¶
In the past, Microsoft was criticised for numerous defects, and its web server software was even recommended to be avoided. In 2002, Microsoft issued the “Trustworthy Computing” initiative, the goal of which was to improve software security. The initiative was put into practice by improving the software development process, gradually leading to Microsoft’s Secure Software Development Lifecycle (SDL), whose principles Microsoft subsequently published. The abbreviations SSDL and SDLC are also used for secure software development models. Microsoft’s SDL was developed from the perspective of a large company, but its principles can also be applied to smaller-scale software development. Microsoft has published a version of the model for SMEs as well, but there are other models too, including those from OWASP and models designed for specific types of systems (see the next section).
A characteristic feature of SDL is that security is taken into account from the very beginning as part of software development: for example, security objectives are defined for the software being developed, security-improving tools are made mandatory, and roles are assigned to people involved in software development to promote security. One such role may be ensuring that the defined security objectives are achieved.
Microsoft’s SDL includes, among other things, the following elements:
- Training is an important way to improve competence so that software developers know the correct practices and learn the technical details that enhance software security.
- Security requirements are important because they guide secure software development and make it possible to define the security of a program. One example of a security requirement may be that the program must contain no SQL vulnerabilities. This can then be verified through testing, code reviews, and static analysis. Another example is requiring the use of specific static analysers at designated stages of software development, with static analysis reporting no vulnerabilities. Security requirements must be updated as threats evolve. Established processes such as SQUARE (Security Quality Requirements Engineering) have been developed to support the creation of security requirements.
- Metrics. Defining security levels and making decisions in practice requires metrics. Metrics help define the minimum acceptable level of security. One metric is the KPI (Key Performance Indicator), which is used in management decision-making. KPIs describe and measure organisational business performance, but they can also be adapted to software security objectives to describe the security level of software. They can, for example, be used when communicating with senior management. Examples of such KPIs include the number of unresolved vulnerabilities, the average time required to fix a vulnerability, and the expected number of vulnerabilities introduced when writing a given amount of code. In addition, vulnerabilities can be assessed for risk, helping management and others understand the overall situation.
- Compliance with legislation is important for software products as well. In particular, GDPR, the CRA (Cyber Resilience Act), NIS2, and PCI DSS (Payment Card Industry Data Security Standard) are internationally significant. Compliance with the GDPR from a software perspective is discussed in more detail in an earlier module. EU regulation is covered extensively in an even earlier module, including an introduction to the CRA. From December 2027 onwards, the CRA requires that software and devices placed on the market after that date must not contain known vulnerabilities, meaning that records must be maintained of the software libraries used and their vulnerabilities. SBOM (Software Bill of Materials) supports this requirement, as mandated by the CRA.
- Threat modelling in software development considers both the software itself and the data it processes. One model is STRIDE (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege). The terms in the acronym also describe the contents of threat modelling: impersonation, tampering, repudiation, information disclosure, denial of service, and unauthorised privilege escalation. Threat modelling is discussed in more detail in the context of risk management.
- Establish design principles. To make software development cost-effective, it is worthwhile investing in security already during the design phase. An earlier module discusses design principles in depth, and it is worth reviewing the early yet still relevant principles of Saltzer and Schroeder. Their emphasis has evolved somewhat over the past 50 years. For example, it has become increasingly important to design user interfaces so that users naturally make secure choices (see also the module human factors). An addition to the early principles is preparing for updates. Software should be built so that updating it is as safe and effortless as possible.
- Use cryptography correctly. Lack of expertise can lead to serious mistakes in the selection and implementation of cryptography. For example, an insecure encryption algorithm may be chosen, an insecure mode of operation may be used for an otherwise secure algorithm, or, in the worst case, sensitive information may be left completely unencrypted. Developers must become familiar with cryptographic standards and implement cryptography accordingly. An important secure programming principle applies here: “There is no need to reinvent the wheel.” In cryptography, this means identifying and adopting best practices and implementing them correctly in software. It is also important to prepare for the future: cryptographic algorithms should be replaceable, and doing so should be straightforward.
- Choose other security solutions correctly as well. Authentication is in itself part of cryptography, but identity and access management (IAM) and adherence to the principle of defence in depth are not necessarily visible at the algorithmic level. In addition, the threat model may require the collection of log data or other forms of redundancy.
- Manage risks in third-party software components. It is risky for software to depend on third-party software components. In practice, however, this is unavoidable because not everything should be implemented from scratch. Typical examples include calling external APIs and using software libraries. Risks can be managed by regularly monitoring vulnerabilities in third-party components. There must be a prepared plan for addressing vulnerabilities, and the software must be capable of being updated when necessary. Risks can also be reduced by anticipating unpredictable inputs provided by external software components. When selecting external libraries or software, it is worth considering whether they are widely used and still actively maintained. For example, useful libraries can be found on GitHub, but some may be marked as archived, meaning they are no longer updated.
- Use approved tools. The organisation should define approved tools, their configurations, and their use as part of the software development process. For example, it should define which compilers may be used and the settings with which they are run.
- Perform static analysis. Static analysis tools and code reviews are an important part of software development. The organisation should designate approved static analysers and their configurations and define the requirements that software must satisfy before it can be approved at various stages of development. These requirements and tools should be updated as necessary.
- Perform dynamic analysis. DAST (Dynamic Application Security Testing) is performed while the program is running in order to test its behaviour and identify errors and vulnerabilities. DAST often includes prebuilt tools and attack techniques. Fuzz testing is frequently incorporated as part of DAST. Like static analysis, DAST can be integrated into the software development pipeline. DAST can therefore be viewed as automated penetration testing.
- Perform penetration testing. Penetration testing is usually carried out either by an internal organisational team or by an external consultant. The objective of penetration testing is to discover vulnerabilities and errors in software so that they can be corrected. A widely used framework for penetration testing is the OWASP Top 10 list.
- Implement a process for security incidents. Despite all precautions, it must be assumed that software vulnerabilities or other security incidents will eventually require a response. It is therefore important to prepare in advance. For this purpose, an Incident Response Plan (IRP) is developed. The IRP should include points of contact for security incidents and emergencies, procedures for resolving vulnerabilities and mitigating their impact, and procedures for communicating with customers, users, and authorities. The IRP should also take into account third-party software and components on which dependencies exist. The IRP should be tested regularly and improved based on observations.