CISSP Domain 8 is focused on helping security professionals to understand, apply, and enforce software security, otherwise referred to as "application security." Releasing new software full of bugs and vulnerabilities is one of the biggest threats to an organization's security, and software development environments have become increasingly complex nowadays.
In this regard, Domain 8 of the ISC2 CISSP Certification focuses on Software Development Security. As a learner, you need to learn the basic principles behind a secure design, build, and test of enterprise applications. Security must also be prioritized during application operations, decommissioning, and disposal phases.
In this article, we'll share the key concepts you need to know in every chapter to learn and pass CISSP domain 8.
8.1 Understand and integrate security in the software development life cycle (SDLC)
Security's involvement in development
The best type of security is what is designed into architecture. Security needs to be involved from the perspective of designing the right level of protection based on requirements and therefore needs to be involved in the early phases of software development and throughout each of the subsequent phases.
Similar to when a system reaches end of life and is retired, when an application reaches the end of life, security must also be involved to ensure proper archival and disposal.
SDLC and SLC
Security needs to be included as an integral part of the software development life cycle (SDLC) as well as the system life cycle (SLC).
The SDLC/SLC include management involvement and approval as well post-deployment activities related to operations as well as decommissioning and disposal. Regardless of the phase, security should be involved.
Risk analysis and threat modeling are critical components of the early phases. It continues through to the architecture and design phase, where the application's architecture is considered in the context of existing infrastructure and systems. Also, at this point, specifically where design is concerned, threat modeling is used to determine what security elements should be incorporated into the application's design.
Development and maintenance life cycle
Historically, development methodology has typically followed what's known as a "waterfall" approach, which is simply a phased, step-by-step approach to software development. To move to the next phase, the previous one must be completed. Sign-offs and approvals mark each phase.
How does the development team respond? If they follow a waterfall approach, the owner will likely be told that going backward is impossible. The design is frozen, and that's what will be built; however, all those requests can easily be accommodated later as part of change management, which costs more time and money. This is problematic, and the software development industry has attempted to develop new methodologies to address this and other issues.
In response to structured, potentially timely, and costly software development approaches like waterfall, the industry has developed innovative strategies to accelerate development and still produce quality code. Each of these methodologies reflects the waterfall model, simply with a variation in approach.
These different approaches have been summarized in the following table:
Complete each development phase before flowing—waterfalling—down to the next phase until the process is complete. This model does not allow a previous phase to be revisited.
Structured Programming Development
A logical programming approach that is said to be foundational to object-oriented programming. Structured programming heavily emphasizes structured control flow and aims to improve clarity, quality, and development time.
Divide the development process into multiple, rapid iterations of defining, developing, and deploying, with heavy customer interaction throughout the process.
A risk-driven development process that follows an iterative model while also including waterfall elements. The spiral model follows defined phases to completion and then repeats the process; this model resembles a spiral when mapped to paper.
Development process intended to produce software with a certifiable level of reliability by focusing on defect prevention.
Security must be included throughout the process, whatever methodology or combination of methodologies is used for software development.
Integrated Product Team (IPT)
An integrated product team (IPT) is a team of skilled professionals who each bring specific expertise and skills to a development project.
DevOps refers to integrating and including team members from all relevant areas from the beginning. This unification aims to create a more agile and responsive environment, which is ultimately more efficient and desirable than having separate teams that must complete their work before passing the project along to the next team.
Many traditional security techniques, for example, items like penetration tests, security analysis, and so on, are too slow for rapid iteration of DevOps. However, DevOps should ideally be referred to as DevSecOps, where security is an integral part of the development process.
Incorporating security into DevOps should include the following components and approaches:
- Plan for security
- Strong engagement between developers, operations, and security
- Engage developers
- Develop using secure techniques and frameworks
- Automate security testing, for example, using a robust CI/CD pipeline
- Use traditional techniques sparingly
Other methodologies that improve the development process, even from a security perspective, are known as maturity models and include one known as the Capability Maturity Model (CMM). CMM, sometimes referred to as SW-CMM, offers a structured approach that allows an organization to measure processes and understand where strengths and room for improvement exist.
Software Assurance Maturity Model
OWASP's Software Assurance Maturity Model (SAMM) is, in OWASP's words, "to be the prime maturity model for software assurance that provides an effective and measurable way for all types of organizations to analyze and improve their software security posture. OWASP SAMM supports the complete software life cycle, including development and acquisition, and is technology and process agnostic. It is intentionally built to be evolutive and risk-driven in nature." (https://owaspsamm.org/model/)
Canary testing and deployments
Canary testing and deployments refer to hyperfocused testing of new application code/features by pushing out the changes to a small subset of users versus pushing them out to all users.
Smoke testing focuses on quick preliminary testing after a change is made to identify any simple failures of the most important existing functionality that worked before the change was made.
8.2 Identify and apply security controls in software development ecosystems
Software development overview
Programming languages have evolved over the years as generations, as depicted in the following table:
Type of language
Strings of numbers that the CPU can process
Cryptic as they use symbolic representation
Pascal, C, Cobol, Fortran
C++, Visual Basic, Java
A library is a collection of resources that could be resources specific to one topic or resources that cover a vast array of topics.
If the library's code is accessed while the invoking program is being built, the library is referred to as a static library. Alternatively, if the library is called after the program is executed, the library is referred to as a dynamic or runtime library.
In the context of software and application development, a tool set is a compilation of development tools and utilities that aid the creation of applications. Tool sets are often referred to as software development kits (SDK). Tools and utilities typically include a compiler and debugger, application programming interfaces (APIs), documentation, libraries, and perhaps a development framework.
Integrated Development Environment (IDE)
An integrated development environment is a software application that serves as an umbrella for software development purposes. Typical IDEs include the following:
- Code editor
- Automation tools
Programming language translators
- Assemblers read entire programs and then convert low-level assembly language into machine language.
- Compilers read entire programs and then convert high-level language into machine language.
- Interpreters convert high-level language one line at a time into machine language at runtime.
Runtime refers to the time when code is being executed on a computer.
Continuous Integration, Delivery, and Deployment
Often referred to simply as CI/CD or the CI/CD pipeline, CI/CD is a highly respected practice and approach for DevOps teams to utilize.
Security Orchestration, Automation, and Response (SOAR)
SOAR is a collection of compatible technologies that take input and data from disparate sources—such as other devices, email, Security Information Event Management (SIEM) systems, user submissions, and manual input—and apply rules and workflows aligned to organizational processes and procedures.
Software Configuration Management (SCM)
Software configuration management focuses explicitly on managing changes in software and is part of the overall configuration/change management. Like other configuration/change management activities, SCM best practices include baseline establishment and revision control, build and process management, and the facilitation of solid teamwork among the software development team.
A code repository is, in its simplest form, a storage location for software and application source code. Popular code repositories include GitHub, SourceForge, Project Locker, and SourceRepo.
By focusing on security from the beginning of a project that follows a SecDevOps approach, the right people can help define necessary security requirements.
The starting point must incorporate sound programming practices; otherwise, weak or missing security characteristics could result, leading to an overall very vulnerable application.
A summary of some key terms is as follows:
The ability of an object—a piece of code—to inherit characteristics of previously created objects.
The idea that an object—a piece of code—can be placed inside another. Other objects can be called by doing this, and objects can be protected by encapsulating or wrapping them in other objects.
Like a polymorphic virus that can change its behavior to avoid detection, polymorphism in programming refers to code that can vary based on requirements. Think of it as "smart code" that can understand the environment and respond accordingly to meet the needs presented by objects in the environment.
Polyinstantiation refers to something being instantiated into multiple separate or independent instances.
Obfuscation refers to hiding or obscuring something; code obfuscation refers to hiding or obscuring code to protect it from unauthorized viewing. More specifically, code obfuscation intentionally creates source code that is difficult for humans to understand.
The three main types of obfuscation are:
Modifies the look of the code (changing comments, removing debugging information, and changing the format of the code)
Modifies the data structure
Control Flow Obfuscation
Modifies the flow of control through the code (reordering statements, methods, loops, and creating irrelevant conditional statements
Security of the software environments
Most organizations employ the "best practice" of separating specific components within the software development environment.
DBMS, concurrency, and locks
One of the essential environments driven by applications is a database environment. Databases have been in use for decades. They allow us to store sensitive and valuable information that can be accessed and drive business decisions.
Database Management Systems (DBMS)
Database architecture comprises several components, typically including hardware, software, language (e. g. SQL), users, and data.
RDBMS allow objects and data to be stored and linked together—to be related—to drive better decision-making. Information can be related to other information, thereby driving inference and deeper understanding. A database can contain one or more tables of data, as depicted in the following image:
Attributes and tuples
RDBMS are structured as two-dimensional tables composed of rows and columns, as depicted in the following image:
Columns or fields are called attributes, and records or rows are called tuples.
Primary and foreign keys
A summary of primary and foreign keys is as follows:
- Primary key: one or more columns whose values uniquely identify a tuple (row) within a relational database. For example, AuthorID in the authors' table.
- Foreign key: one or more columns whose values in a table refer to the primary key in another table. AuthorID would be the primary key in the authors' table. Any books in the books table by an author would have a foreign key referring to the author in the authors' table.
Concurrency and locks
Databases are valuable for several reasons, including that they contain up-to-date and relevant information for decision-making purposes. This means that multiple people may sometimes attempt to access or update the same database element simultaneously.
When this happens, integrity issues could arise. As a result, the logic and controls to handle concurrency (the ability for multiple processes to access or change shared data simultaneously) and lock issues are standard within DBMS. To protect the integrity of data elements, when a user accesses an element that is locked, which prevents another user from updating it.
ACID stands for atomicity, consistency, isolation, and durability and relates to how information and transactions in an RDBMS environment should be treated:
Atomicity—All changes take effect or None at all
Consistency—Consistent with the Rules
Isolation—Transactions are Invisible to other users until complete
Durability—Completed changes will not be Lost
The term metadata refers to information that offers insights into other data. Essentially, it's data about data.
CI/CD, SOAR, and SCM are development ecosystems. Though the focus of each is different, they each share common characteristics.
8.3 Assess the effectiveness of software security
Software security assessment methods
Software security effectiveness can be determined through auditing and logging changes, risk analysis, and mitigation, among other methods.
Testing could include white box testing, black box testing, and items like threat modeling and penetration testing. Security should be involved with:
- Risk analysis and mitigation
- Auditing and logging of changes
- Logging and monitoring
- Internal and external audit
- Procurement process
- Certification and accreditation
- Testing and verification
- Code signing
This topic is a quick review of Domain 6.
8.4 Assess security impact of acquired software
Acquiring software should be taken as seriously as developing software, and security should be considered at every step. Software acquisition should require and receive the same level of attention and scrutiny regarding security.
Software assurance phases for acquisition
Software assurance phases for acquisition include:
Among most organizations, COTS software is typically used because it is often readily available to the general public and user-friendly. Additionally, active user communities often develop around COTS software that allows user support, software use scenarios and examples, troubleshooting, and bug reports to become a dynamic and collective community-based effort versus isolated user dependence upon the COTS provider.
Unlike COTS, open source software is software with source code that anyone can inspect, modify, and enhance. As a general rule, open-source software licenses invite collaboration among a user community. An organization may use open-source software for control, training, and security.
Third-party code is code developed by programmers not employed by the organization. The SDLC process should be applied to the extent possible to ensure that the application is secure and functions as expected.
8.5 Define and apply secure coding guidelines and standards
Secure coding guidelines
To produce consistently secure software, it is vital to define and apply safe coding guidelines and best practices.
Every few years, OWASP publishes a Top 10 Web Application Security Risks document that includes a list of risks, their descriptions, and mitigation strategies. Similarly, other organizations, like NIST and CIS, also offer secure software development frameworks and resources devoted to best software development practices.
The following are the most common security weaknesses and vulnerabilities present at the source code level:
- Covert channels
- Buffer overflows
- Memory/object reuse
- Executable mobile code
- Malformed input
- Citizen developers
Buffer overflow is a common problem with applications and happens when information sent to a storage buffer exceeds the buffer's capacity. The vulnerabilities can be exploited to elevate privileges or launch malicious code.
Address Space Layout Randomization (ASLR) is one of the best protection techniques against buffer overflows. In essence, it works by randomizing the locations where system executables are loaded into memory.
Another software development technique commonly used to prevent buffer overflows is bounds checking. The input to a variable should be checked to ensure it is within some bounds before it is used.
Application programming interfaces (APIs)
Application programming interfaces (APIs) provide a way for applications to communicate with each other; APIs act as translators.
Two of the most common APIs are Representational State Transfer (REST) and Simple Object Access Protocol (SOAP).
Representational State Transfer (REST)
Simple Object Access Protocol (SOAP)
Secure coding practices
Secure programming can help prevent software vulnerabilities.
Secure coding practices include:
- Input validation
- Authentication and password management
- Session management
- Cryptographic practices
- Error handling and logging
- System configuration
- File/database security
- Memory management
Coupling and cohesion
Coupling and cohesion are relational terms that indicate the level of relatedness between units of a code base (coupling) and the level of relatedness between the code that makes up a unit of code (cohesion).
Low coupling (meaning units of code can stand alone) and high cohesion (meaning the code that makes up a unit of code is highly related) are optimal.
Polyinstantiation refers to something being instantiated into multiple separate or independent instances. Unauthorized inference can be a particular issue where people and databases are concerned. Most of the time, the inference is a good thing.
Polyinstantiation can be used to prevent unauthorized inference, and it allows the same data to exist at different classification levels.
Software-defined security is security in a computing environment that is implemented, controlled, and managed by software. As with other software-defined functions, the development and growth of software-defined security have coincided with the continued growth of cloud and virtualization.
Software development vulnerabilities
Software development vulnerabilities often arise because of:
- Use of insecure coding practices
- Citizen developers writing code
Citizen developers often have access to powerful programming tools. Still, they're typically self-taught and unskilled regarding secure coding practices, leading to insecure and unreliable application development. Insecure coding practices can lead to backdoor or trapdoor situations, whereby an attacker can bypass normal authentication mechanisms as a result of installing remote access software on a computer, as well as attacks like:
Memory reuse (object reuse)