Secure Software Development
Fundamental Practices for Secure Software Development: Essential Elements of a Secure Development Lifecycle Program
https://safecode.org/resource-secure-development-practices/fundamental-practices-secure-software-development-2/ SAFECode / CIS March 2018
- Foundational set of secure development practices that have been effective in improving software security in real-world implementations by SAFECode members across their diverse development environments and product lines. These were identified through an ongoing collaboration among SAFECode members and are “practiced practices”.
- SAFECode members agree that to be effective, software security must be addressed throughout the software development lifecycle, rather than as a one-time event or single box on a checklist.
- Software assurance cannot be achieved by a single practice, tool, heroic effort or checklist; rather it is the result of a comprehensive secure software engineering process that spans all parts of development from early planning through end of life.
- It is also important to realize that, even within a single organization and associated Secure Development Lifecycle (SDL), there is no one-size-fits-all approach.
- A key principle for creating secure code is the need for an organizational commitment starting with executive-level support, clear business and functional requirements, and a comprehensive secure software development lifecycle that is applicable throughout the product's lifecycle and incorporates training of development personnel.
- We believe that every technology developer has a responsibility to implement and take part in such a process. This is fundamental to achieving a "security culture" in a software organization.
- The practices identified in this document and application security controls they drive will lead to the identification of software design or implementation weaknesses, which when exploited expose the application, environment or company to a level of risk. These issues must be tracked and action must be taken to improve the overall security posture of the product.
-
Further, effective tracking supports the ability to both gauge compliance with internal policies and external regulations and define other security assurance metrics.
-
Regardless of the development methodology being used, defining application security controls begins in (or even before) the Design stage and continues throughout an application’s lifecycle in response to changing business requirements and an ever-evolving threat environment.
- At a high level, the workflow should include:
- Identifying threats, risks and compliance drivers faced by this application
- Identifying appropriate security requirements to address those threats and risks
- Communicating the security requirements to the appropriate implementation teams
- Validating that each security requirement has been implemented
- Auditing, if required, to demonstrate compliance with any applicable policies or regulations
Design
- The principles of secure system design were first articulated in a 1974 paper by Jerome Saltzer and Michael Schroeder
-
Additional principle: Design for updating: no system is likely to remain free from security vulnerabilities forever, so developers should plan for the safe and reliable installation of security updates.
-
Threat modeling is a security focused design activity and a fundamental practice in the process of building trusted technology; it has proven to be one of the best “return on investment” activities for identifying and addressing design flaws before their implementation into code.
-
The greatest benefit from threat modeling is realized when it is performed early in the development lifecycle before code is committed. Even if that cannot be achieved, threat modeling provides value in mapping out a system to understand and prioritize its weaknesses.
-
Develop an Encryption Strategy When storing data in a persistent location, organizations should develop clear criteria for what types of data should be encrypted, and what mechanisms are acceptable to protect that data.
- Rather than having developers figure out the correct choice at the time of implementation, organizations should develop clear encryption standards. Only industry-vetted encryption libraries should be used, rather than custom internal implementations.
- Solutions such as disk encryption, OS credential/key managers, and database transparent encryption are relatively easy to deploy and provide protection against offline attack. If the primary risk is theft of a device or disk, these solutions are typically the best option, as they require little to no custom application logic to implement, and most cloud and mobile platforms make enabling this form of storage encryption quite easy.
- However, these solutions do not protect against any compromise of application logic and are insufficient protection for very sensitive or highly confidential data. For these scenarios the application must implement encryption specifically against the data prior to writing it to storage.
-
Hard-coding encryption keys (or other secrets) within source code leaves them very vulnerable and must be avoided.
-
Standardize Identity and Access Management Most products and services have the need to verify which principal, either human user or other service or logical component, is attempting to perform actions and whether the principal in question is authorized to perform the action it is attempting to invoke. These actions should all be auditable and logged in the logging system being used. Organizations should standardize on an approach to both authentication and authorization. This provides consistency between components as well as clear guidance on how to verify the presence of the controls.
-
Establish Log Requirements and Audit Practices. FINIRE
Secure by Design: A Guide to Assessing Software Security Practices
https://www.cisecurity.org/insights/white-papers/secure-by-design SAFECode / CIS October 2025
-
An organizational culture that prioritizes security must underlie implementation of engineering and operational practices for SbD. It is difficult to assess culture and commitment to SbD in isolation but easy to tell whether they are present.
-
Secure by Design encompasses what developers call “design” as well as security of implementation and security of default configuration. The objective of Secure by Design is that systems and particularly software be “sufficiently secure” to meet the needs of the end users/organizations that rely on them and that those end users/organizations have a sound way to evaluate that sufficiency.
Secure software design
- It begins with a set of:
- Security objectives that the software must satisfy
- Security threats that the software should resist.
- Although specific systems — especially systems targeted at specific applications or customers — may have very specific objectives, most commercial products and online services are designed to meet more general classes of objectives. The fundamental requirements for any secure system are usually confidentiality, integrity, and availability. A fourth common requirement is accountability.
- Secure system design teams in industry frequently rely on a process called threat modeling to review their designs. Threat modeling does not focus on threats in the sense of a hostile agent who seeks to undermine system security. Rather, the designer analyzes a data flow diagram of a system to identify:
- points where an attacker might undermine the system’s security and approaches to countering those attacks;
- specific action items for designers and developers to make software more resistant to attack.
Secure development processes
- At a high level, all secure development processes are similar and encompass the practices enumerated in the SSDF. However, the details of each software development organization’s practices are likely to differ.
- A secure development process must include:
- A “bug bar” that identifies “must fix” coding errors whose presence would block software from being released.
- Coding standards and requirements
- Such as using only “safe” runtime libraries, memory-safe languages, and approved encryption software.
- Enabling security or mitigation features that make it difficult or impossible to exploit vulnerabilities that may have gone undetected by the secure development process and remain in software.
- Requirements to use organization-validated and actively supported third-party and open-source components.
- Requirements to use specific configuration, development, and security tools including:
- Compilers
- Static analysis tools that detect coding errors (especially memory safety errors)
- Configuration security tools that ensure that installation of the software does not undermine the security by default of the software itself or the underlying platform
- Dynamic analysis tools that test components for dangerous responses to unexpected inputs
- Requirements for security-related testing beyond dynamic analysis — for example, regression testing to ensure that previously eliminated vulnerabilities have not been reintroduced or adversarial penetration testing.
- Training of development staff to follow the practices and meet the requirements of the process.
Secure default configuration
- Software products frequently include myriad configuration settings and options that system administrators may use to enable or disable features or adjust product behavior. Although users can adjust those settings, many will fail to do so. Experience has shown that many users and administrators accept default settings. To the extent that the default settings:
- leave more software features and interfaces exposed, they increase the risk of misconfiguration and a successful attack on software security.
- make permissive choices for security settings such as password length, file access permissions, or use of encryption, they make an attacker’s task easier.
- Software development organizations must seek to make their products “secure by default.” A simple definition of “secure by default” is that the software blocks access to any function or interface that is potentially dangerous or not required by almost all users of the product and configures all other options by default in a secure manner (opt-out of secure configuration rather than opt-in) and defaults to the most secure acceptable configuration of features and mechanisms.
- The term “attack surface” refers to the set of exposed interfaces and functions in a software product (enabled network ports and protocols, usable software features, privileges, options, and accessible files).
- The software product, or the underlying operating system platforms must provide features for controlling access to elements of the attack surface.
- The design and development team must evaluate each element of the attack surface to determine whether it is widely needed by users or whether it should be disabled by default.
- A good rule of thumb is that if a feature, privilege, or interface is not required by 80% of users, it must be disabled by default.
Supply chain security
- Challenge to Secure by Design that is posed by software development organizations’ use of software that they did not themselves create (often referred to as “third-party code”).
- Software development organizations that integrate third-party code (TPC) assume responsibility for ensuring that software does not undermine the security of their integrated product.
- Ideally, they must be assured that the third party developer adheres to the requirements of the SSDF, for example by having a contract with the third-party developer or by auditing the third-party developer in accordance with the recommendations of this paper (or both).
- Many software development organizations enforce policies that only approved TPC can be included and maintain repositories of vetted TPC for use in products or services.
- Where the third-party falls short, the relying software development organization must take steps to fill the gap, for example assessing the risk that the TPC might pose and performing internal reviews, code scans, or tests.
- Software development organizations have adopted the concept of a Software Bill of Material (SBOM) to track their dependence on TPC. An SBOM specifies the specific version of a software component and its origin. End users/organizations sometimes request access to products’ SBOMs to gain confidence in the software they are acquiring, but the onus of understanding and addressing third-party risk falls on the software development organization. The SBOM can be an important aid to knowing when a reported vulnerability affects a third-party component, but only the developer can fully understand and remediate the risk inherited from vulnerable TPC.
- The concept of supply chain security applies not only to software components that are integrated into a monolithic product or online service, but also to components that are invoked remotely in a distributed or cloud environment.
Code integrity
- Ensuring that the software that end users/organizations rely on is the software that they intended to deliver. For example, a malicious party might introduce a design or coding error into source code or binaries or manipulate the final product before delivery to its end users/organizations.
- Preserving software integrity involves:
- maintaining control over the design and code to make sure that only authorized and intended changes are made; and,
- those changes are tracked and traceable to individual developers.
- That control is:
- in part the domain of common software development practices (change control, version control, configuration management, code signing);
- in part the domain of operational security (configuration of development systems to enforce least privilege and zero trust, and ensure proper authentication, authorization, and auditing of developers’ actions) of the development organization’s IT environment.
Vulnerability remediation
- Vulnerability response and remediation are part of any secure development process.
- Development teams must implement processes to accept reports of product vulnerabilities, investigate the reports, and remedy the vulnerabilities.
- They must ensure that vulnerability advisories and fixes are communicated to their users, ideally in a standardized form such as Common Security Advisory Framework (CSAF) and accompanied by context on their severity and exploitability.
- All software development organizations must be prepared to
- accept vulnerability reports,
- respond,
- do root cause analysis,
- and track their work.
- Software development organizations must not only fix the vulnerabilities that are reported to them but also search for other similar vulnerabilities that have not yet been discovered and use the results of root cause analysis as input to process improvement — by updating tools or building new ones, by updating training, and by revising threat models and updating default configurations.
Assessment and evidence
- The natural question now becomes: how does one know that the various principles and considerations above have been followed?
- Customers and regulators may ask software development organizations to demonstrate that their
products are “secure by design.” That does not mean that the software is vulnerability-free — there is no such thing. Rather, it means that the software development organization has addressed the six considerations listed above. - Of the six considerations, the first three — design, secure development, and default configuration — are the primary focus of the software development organization.
-
The evidence of organizational commitment will vary widely from one software development organization to the next, depending on culture, personalities, and history. Evidence of organizational commitment must be considered in the context of the evidence and effectiveness of the software development organization’s actions in response to the six considerations.
-
The end product of secure software design is source code and binaries. However, it is not practical to assure or assess the security of source code and binaries in isolation, so development teams apply processes and tools and create supporting artifacts that facilitate both secure development and security assessment:
- threat models
- test results
- outputs of scanning tools.
-
Evidence that is created solely to satisfy an assessor or evaluator should be considered with great suspicion because it may not actually be connected to the software.
-
Measures of confidence in the security attributes of a product or service are usually broken down into two broad categories:
- Does the product or service meet requirements for security functions or features that enable it to protect information?
- Has the product or service been developed so that it is assured to be free from exploitable vulnerabilities — from errors that would allow an adversary to defeat its security functions?
- Confidence in the presence and correct implementation of some security features can be gained by testing the features to ensure that they meet their specifications or, in some cases, by mathematically verifying their correctness. Testing is insufficient to confirm that a system is free from exploitable errors — any finite amount of testing can confirm the presence of errors, but not their absence.
- The process of gaining confidence that a system is free from exploitable errors is referred to as assurance. Assurance addresses both the security of the implementation of the system and the ability of the system’s security features and their configuration to resist attack.
-
See “CIS controls” / NIST SSDFin the appendix (it is another document).
-
For the software security team, the “product” is the secure development process that the development teams must execute. The secure development process tells the developers:
- which development, analysis, and testing tools they must run,
- what secure coding conventions they must follow,
- which tool outputs represent “must fix” and “should fix” bugs,
- which analysis and design steps they must follow (e.g., threat modeling).
- Just as the developers maintain their code in controlled repositories and track their work items in bug tracking systems, the security team tracks the evolving process in a repository and uses a bug tracking system to control changes.
- It is reasonable for a software development organization to be expected to publish its secure development process, or at least to make it available for review under NDA.