What are vulnerabilities in cyber security?
A secure software development framework (SSDF) of fundamental, sound secure software development practices based on established secure software development practices.
Few software development life cycle (SDLC) models explicitly address software security in detail, so secure software development practices usually need to be added to each SDLC model to ensure the software being developed is well secured.
Following these practices should help software developers reduce the number of vulnerabilities in released software, mitigate the potential impact of the exploitation of undetected or unaddressed vulnerabilities, and address the root causes of vulnerabilities to prevent future recurrences. Software consumers can reuse and adapt the practices in their software acquisition processes.
A software development life cycle (SDLC) is a formal or informal methodology for designing, creating, and maintaining software. There are many models for SDLCs, including waterfall, spiral, agile, and Development and Operations (DevOps).
Regardless of which SDLC model is used to develop software, secure software development practices should be integrated throughout it for three reasons:
- to reduce the number of vulnerabilities in released software
- to mitigate the potential impact of the exploitation of undetected or unaddressed vulnerabilities
- to address the root causes of vulnerabilities to prevent future recurrences
Most aspects of security can be addressed at multiple places within an SDLC, but in general, the earlier in the SDLC security is addressed, the less effort is ultimately required to achieve the same level of security.
There are many existing documents on secure software development practices. Here, we does not introduce new practices or define new terminology; instead, we describes a subset of high level practices based on established standards, guidance, and secure software development practice documents. These practices, collectively called a secure software development framework (SSDF), should be particularly helpful for the target audiences to achieve security software development objectives.
Expertise in secure software development is not required to understand theses practices. This helps facilitate communications about secure software practices amongst both internal and external organizational stakeholders, including:
- Business owners, software developers, and cybersecurity professionals within an organization
- Software consumers, businesses and other organizations that want to define required or desired characteristics for software in their acquisition processes in order to have higher-quality software (particularly with fewer security vulnerabilities)
- Software producers (e.g., commercial-off-the-shelf [COTS] product vendors, government off-the-shelf [GOTS] software developers, software developers working within or on behalf of software consumer organizations) that want to integrate secure software development practices throughout their SDLCs, express their secure software practices to their customers, or define requirements for their suppliers
These practices are not based on an assumption of all organizations having the same security objectives and priorities. Rather, the recommendations reflect that each software producer may have unique security assumptions and each software consumer may have unique security needs. While the desire is for each security producer to follow all applicable practices, the expectation is that the degree to which each practice is implemented will vary based on the software producer’s security assumptions. The practices provide flexibility for implementers, but they are also clear to avoid leaving too much open to interpretation.
Secure Software Development Framework (SSDF)
Although most practices are relevant for any software development effort, some practices are not always applicable. For example, if developing a particular piece of software does not involve using a compiler, there would be no need to follow a practice on configuring the compiler to improve executable security.
Prepare the Organization
Define Security Requirements for Software Development
Ensure security requirements for software development are known at all times so they can be taken into account throughout the SDLC, and duplication of effort can be minimized because the requirements information can be collected once and shared. This includes requirements from internal sources, such as the organization’s policies, business objectives, and risk management strategy, and external sources, such as applicable laws and regulations.
Implement Roles and Responsibilities
Ensure everyone inside and outside the organization involved in the SDLC is prepared to perform their SSDF related roles and responsibilities throughout the SDLC.
Create new roles and alter responsibilities for existing roles to encompass all parts of the SSDF. Periodically review the defined roles and responsibilities, and update them as needed.
- Define SSDF-related roles and responsibilities for all members of the software development team.
- Integrate the security roles into the software development team.
- Define roles and responsibilities for cybersecurity staff, security champions, senior management, software developers, product owners, and others involved in the SDLC.
- Conduct an annual review of all roles and responsibilities.
- Educate affected individuals on the impending changes in roles and responsibilities
Implement a Supporting Toolchain
Use automation to reduce the human effort needed and improve the accuracy, consistency, and comprehensiveness of security practices throughout the SDLC, as well as a way to document and demonstrate use of these practices without significant additional effort or expense.
Specify which tools or tool types are to be included in each toolchain and which tools or tool types are mandatory, along with how the toolchain components are to be integrated with each other.
- Define categories of toolchains, and specify the mandatory tools or tool types to be used for each category.
- Use automated technology for toolchain management and orchestration.
- Identify security tools to integrate into the developer toolchain.
Following sound security practices, deploy and configure tools, integrate them within the toolchain, and maintain the individual tools and the toolchain as a whole.
- Evaluate, select, and acquire tools.
- Integrate tools with other tools and with existing software development processes and workflows.
- Update, upgrade, and replace existing tools.
- Monitor tool logs for potential operational and security issues.
Configure tools to collect evidence and artifacts of their support of the secure software development practices.
- Use the organization’s existing workflow or bug tracking systems to create an audit trail of secure development-related actions performed.
- Determine how often the collected information should be audited, and implement processes to perform the auditing.
Define criteria for software security checks at one or more points within the SDLC.
- Ensure the criteria adequately indicate how effectively security risk is being managed. * Define key performance indicators (KPIs) for software security.
- Add software security criteria to existing checks (e.g., the Definition of Done in agile SDLC methodologies).
- Review the artifacts generated as part of the software development workflow system to determine if they meet the criteria purposes.
- Record security check approvals, rejections, and requests for exception as part of the workflow and tracking system
Implement processes, mechanisms, etc. to gather the necessary information in support of the criteria.
- Use the toolchain to automatically gather information that informs security decision making.
- Deploy additional tools if needed to support generation and collection of information supporting the criteria.
- Automate decision making processes utilizing the criteria.
Protect Software
Protect All Forms of Code from Unauthorized Access and Tampering
Help prevent unauthorized changes to code, both inadvertent and intentional, which could circumvent or negate the intended security characteristics of the software. For code not intended to be publicly accessible, it helps prevent theft of the software and makes it more difficult for attackers to find vulnerabilities in the software.
Store all forms of code, including source code and executable code, based on the principle of least privilege so that only authorized personnel have the necessary forms of access. The protection needed will vary based on the nature of the code. For example, some code may be intended for public access, in which case its integrity and availability should be protected; other code may also need its confidentiality protected.
- Store all source code in a code repository, and restrict access to it.
- Use version control features of the repository to track all changes made to code with accountability to the individual developer account.
- Use code signing to help protect the integrity and provenance of executables.
- Use cryptographic hashes to help protect the integrity of files.
- Create and maintain a software bill of materials (SBOM) for each piece of software stored in the repository.
Provide a Mechanism for Verifying Software Release Integrity
Help software consumers ensure the software they acquire is legitimate and has not been tampered with.
- Store all source code in a code repository, and restrict access to it.
- Use version control features of the repository to track all changes made to code with accountability to the individual developer account.
- Use code signing to help protect the integrity and provenance of executables.
- Use cryptographic hashes to help protect the integrity of files.
- Create and maintain a software bill of materials (SBOM) for each piece of software stored in the repository.
Make verification information available to software consumers.
- Post cryptographic hashes for release files on a well-secured website.
- Use an established certificate authority for code signing so consumers can confirm the validity of signatures.
- Periodically review the code signing processes, including certificate renewal and protection.
Archive and Protect Each Software Release
Securely archive a copy of each release and all of its components, such as code, package files, third-party libraries, documentation, and release integrity verification information.
Store all release files in a repository, and restrict access to them.
Produce Well-Secured Software
Take Security Requirements and Risk Information into Account During Software Design
Determine which security requirements the software’s design should meet, and determine what security risks the software is likely to face during production operation and how those risks should be mitigated by the software’s design. Addressing security requirements and risks during software design instead of later helps to make software development more efficient.
Use threat modeling, attack modeling, attack surface mapping, and/or other forms of risk modeling to help assess the security risk for the software.
- Train the development team to create threat models and attack models, and to analyze how to address the risks and implement mitigations.
- Perform more rigorous assessments for high-risk areas, such as protecting sensitive data.
- Review vulnerability reports and statistics for previous software.
Review the Software Design to Verify Compliance with Security Requirements and Risk Information
Help ensure the software will meet the security requirements and satisfactorily address the identified risk information.
Have someone qualified who was not involved with the software design, review it to confirm it meets all the security requirements and satisfactorily addresses the identified risk information.
- Review the software design to confirm it addresses all the security requirements.
- Review the risk models created during software design to determine if they appear to adequately identify the risks.
- Review the software design to confirm it satisfactorily addresses the risks identified by the risk models.
- Have the software designer correct all failures to meet the requirements.
Verify Third-Party Software Complies with Security Requirements
Reduce the risk associated with using acquired software modules and services, which are potential sources of additional vulnerabilities.
Communicate requirements to vendors, open source communities, and other third parties who may provide software modules and services to the organization for reuse by the organization’s own software.
- Define a core set of security requirements, and include them in acquisition documents, software contracts, and other agreements with third parties.
- Define the security-related criteria for selecting commercial and open source software.
- Require the providers of commercial software modules and services to provide evidence that their software complies with the organization’s security requirements.
Use appropriate means to verify commercial and open source third-party software modules and services comply with the requirements.
- See if there are publicly known vulnerabilities in the software modules and services that the vendor has not yet fixed.
- Ensure each software module or service is still actively maintained, especially remediating new vulnerabilities found in the software.
- Determine a plan of action for each thirdparty software module or service no longer being maintained or available in the future.
Reuse Existing, Well-Secured Software When Feasible Instead of Duplicating Functionality
Lower the costs of software development, expedite software development, and decrease the likelihood of introducing additional security vulnerabilities into the software. These are particularly true for software that implements security functionality, such as cryptographic modules and protocols.
Acquire well-secured software libraries, modules, middleware, frameworks, and other components from third parties for use by the organization’s software.
- Review and evaluate the third-party software components in the context of their expected use. If a component is to be used in a substantially different way in the future, perform the review and evaluation again with that new context in mind.
- Establish an organization-wide software repository to host sanctioned and vetted open source components.
- Maintain a list of approved commercial software components and component versions.
- Designate which components must be included by software to be developed.
Create well-secured software components in-house following SDLC processes to meet common internal software development needs that cannot be better met by third-party software.
- Follow the organization-established security practices for secure software development.
- Maintain an organization-wide software repository for these components.
- Designate which components must be included by software to be developed.
Where appropriate, build in support for using standardized security features and services, such as integrating with log management, identity management, access control, and vulnerability management systems.
- Maintain an organization-wide software repository of modules for supporting standardized security features and services.
- Designate which security features and services must be supported by software to be developed.
Create Source Code Adhering to Secure Coding Practices
Decrease the number of security vulnerabilities in the software, and reduce costs by eliminating vulnerabilities during source code creation.
Follow all secure coding practices appropriate to the development languages and environment.
- Validate all untrusted input, and validate and properly encode all output.
- Avoid using unsafe functions and calls.
- Handle errors gracefully.
- Provide logging and tracing capabilities.
- Use development environments with features that encourage or require the use of secure coding practices.
- Follow procedures for manually ensuring compliance with secure coding practices.
Have the developer review their own human readable code, analyze their own human-readable code, and/or test their own executable code
Configure the Compilation and Build Processes to Improve Executable Security
Use compiler and build tools that offer features to improve executable security. Consider replacing older compiler and build tools with up-to-date versions.
Determine which features should be used and how each feature should be configured, then implement the approved configuration for compilation and build tools, processes, etc.
- Enable compiler features that produce warnings for potentially poorly secured code during the compilation process.
- Enable compiler features that randomize characteristics, such as memory location usage, that would otherwise be easily predictable and thus exploitable.
- Conduct testing to ensure the features are working as expected and not inadvertently causing any operational issues or other problems.
- Verify the approved configuration is enabled for compilation and build tools, processes, etc.
- Document information about the compilation and build tool configuration in a knowledge base that developers can access and search.
Review and/or Analyze Human-Readable Code to Identify Vulnerabilities and Verify Compliance with Security Requirements
Help identify vulnerabilities before software is released so they can be corrected before release, which prevents exploitation. Using automated methods lowers the effort and resources needed to detect vulnerabilities. Human readable code is source code and any other form of code an organization deems as human readable.
Determine whether code review (a person directly looks at the code to find issues) and/or code analysis (tools are used to find issues in code, either in a fully automated way or in conjunction with a person) should be used.
Perform the code review and/or code analysis, and document and triage all discovered issues and recommended remediations in the development team’s workflow or bug-tracking system.
- Have developers review their own code.
- Perform peer review of code.
- Use peer reviewing tools that facilitate the peer review process and document all discussions and other feedback.
- Use a static analysis tool to automatically check code for vulnerabilities and for compliance with the organization’s secure coding standards, with a human reviewing issues reported by the tool and remediating them as necessary.
- Use review checklists to verify the code complies with the requirements.
- Use automated tools to identify and remediate documented and verified unsafe software practices on a continuous basis as human-readable code is checked into the code repository.
- Identify and document the root cause of each discovered issue.
- Document lessons learned from code review and analysis in a knowledge base.
Test Executable Code to Identify Vulnerabilities and Verify Compliance with Security Requirements
Help identify vulnerabilities before software is released so they can be corrected before release, which prevents exploitation. Using automated methods lowers the effort and resources needed to detect vulnerabilities. Executable code is binaries, directly executed bytecode, directly executed source code, and any other form of code an organization deems as executable.
Determine if executable code testing should be performed and, if so, which types should be used.
Design the tests, perform the testing, and document the results.
- Perform robust functional testing of security features.
- Integrate dynamic vulnerability testing into the project’s automated test suite.
- Incorporate tests for previously reported vulnerabilities into the project’s automated test suite to ensure that errors are not reintroduced.
- Use automated fuzz testing tools to find issues with input handling by native code.
- Use penetration testing to simulate how an attacker might attempt to compromise the software only in high-risk scenarios if resources are available.
- Use automated tools to identify and remediate documented and verified unsafe software practices on a continuous basis as executable code is checked into the code repository.
- Identify and document the root cause of each discovered issue.
- Document lessons learned from code testing in a knowledge base that developers can access and search.
Configure the Software to Have Secure Settings by Default
Help improve the security of the software at installation time, which reduces the likelihood of the software being deployed with weak security settings that would put it at greater risk of compromise.
Determine how to configure each setting that has an effect on security so the default settings are secure and they do not weaken the security functions provided by the platform, network infrastructure, or services.
Conduct testing to ensure the settings are working as expected and not inadvertently causing any security weaknesses, operational issues, or other problems.
- Implement the default settings and document each setting for software administrator.
- Verify the approved configuration is in place for the software.
- Document each setting’s purpose, options, default value, security relevance, potential operational impact, and relationships with other settings.
- Document how each setting can be implemented by software administrators.
Respond to Vulnerability Reports
Identify and Confirm Vulnerabilities on an Ongoing Basis
Help ensure vulnerabilities are identified more quickly so they can be remediated more quickly, reducing the window of opportunity for attackers.
Gather information from consumers and public sources on potential vulnerabilities in the software and any third-party components the software uses, and investigate all credible reports.
- Establish a vulnerability response program, and make it easy for security researchers to learn about your program and report possible vulnerabilities.
- Monitor vulnerability databases, security mailing lists, and other sources of vulnerability reports through manual or automated means.
Periodically review, analyze, and/or test the software’s code to identify previously undetected vulnerabilities. Configure the toolchain to perform automated code analysis and testing on a regular basis.
Have an incident response capability to coordinate response to vulnerability reports.
- Have a policy that addresses vulnerability disclosure and remediation, and implement the processes needed to support that policy.
- Have a security response playbook to handle a generic reported vulnerability, a report of zero-days, a vulnerability being exploited in the wild, and a major ongoing incident involving multiple parties.
Assess and Prioritize the Remediation of All Vulnerabilities
Help ensure vulnerabilities are remediated as quickly as necessary, reducing the window of opportunity for attackers.
Analyze each vulnerability which is not being exploited to determine how much effort would be required to remediate it, what the potential impact of vulnerability exploitation would be, what resources are required to weaponize the vulnerability (with the assumption that the vulnerability will be exploited in the near future), and how vulnerability remediation should be prioritized, along with any other relevant factors.
Use issue tracking or bug tracking software to document each vulnerability.
Analyze Vulnerabilities to Identify Their Root Causes
Help reduce the frequency of vulnerabilities in the future.
- Document the root cause of each discovered issue.
- Document lessons learned from root cause analysis in a knowledge base that developers can access and search.
Analyze the root causes over time to identify patterns, such as when a particular secure coding practice not being followed consistently.
Review the software for other instances of the reported problem and fix them proactively rather than waiting for external reports.
Review the SDLC process and update it as appropriate to prevent (or reduce the likelihood of) the root cause recurring in updates to this software or in new software that is created.
- Document lessons learned from root cause analysis in a knowledge base that developers can access and search.
- Plan and implement changes to the appropriate SSDF practices.