CISSP Development Methodologies – Bk1D8T1St1P4

Microsoft Security Development Lifecycle

CISSP Development Methodologies in this the Microsoft SDL is a software development process that helps developers build more secure software and address security compliance requirements while reducing development cost. It prescribes best practices, processes, standards, security activities, and tools in an approach to implement an SDL program.

The SDL is intended for use by a variety of different organizations of different sizes and capabilities. It includes an optimization model to guide SDL adoption and practice maturity improvements. Security roles and responsibilities are outlined.

The SDL is designed to apply to a standard development lifecycle as well as to an agile approach. It maps security activities to software development phases. The software development phases covered by the SDL are training, requirements, design, implementation, verification, release, and response.

The SDL has 17 mandatory SDL activities that are required practice to prove compliance with the program. These practices are grouped by how they apply to different software development phases. Each practice consists of references, materials, and training to support its focus. Guidance is given on when to apply each practice to either a traditional SDLC phase or an aspect of an agile practice. Agile methodology is further discussed in the “Software CISSP Development Methodologies” section of this chapter.

Microsoft SDL practices per phase are shown in Table 8.1.

CISSP Development Methodologies

CISSP Development Methodologies

The SDL also recommends optional security practices whose performance should  be considered with critical security software. Some examples of these optional practices are manual code reviews, penetration testing, and vulnerability analysis of related software.

The standard has an Application Security Verification Process. Having a systematic SDLC security practice is one thing, proving that it is being followed is much better. Microsoft’s SDL includes requirements and direction to verify that the SDL is being performed in its Application Security Verification Process. This process describes the processes and actors, the data collection, and supportive elements to verify that the SDL is being followed.

Microsoft’s SDL is useful for addressing compliance requirements with a proactive and future proofing approach designed to address ever-changing regulations. Adherence to the program lowers the total cost of development as well. Finding and fixing vulnerabilities early, for instance in the design phase, is significantly more cost-effective than doing the same during the testing phase.

For more information about the SDL, see https://www.microsoft.com/en-us/sdl.

Software Language Concepts

Programming languages are the means by which correlated sets of instructions are written to produce programs that can be executed by a computer. Programming language grammar consists of symbols that describe different data types, methods to create and manipulate data, and logical structures that can control the flow of execution of the program.

Language Types

CISSP development methodologies in this explaining the two types of software languages: compiled and interpreted. Each language type has security implications for the software that it is used to produce.

Compiled

Compiled languages are those where the program instructions are translated into a form that is directly interpretable by the machine. A program called a compiler does this translation. An advantage of compiled languages is that the compiler is typically optimized for the target hardware. And because of this translation into a machine code, compiled languages typically execute faster than interpreted languages.

Compiled languages have many features that support security. The compilation process checks the program structure for correctness. A security type system can be employed at compile time to enforce information flows to verify or report violations of confidentiality or integrity. It is possible to generate a certificate during compilation as   a form of proof that the source code was compiled following a set of rules that satisfies a security policy.

Interpreted

An interpreted programming language is one where most of its code is executed directly without first having to compile it into machine-language instructions. Many developers favor interpreted languages for how quickly they can be used to write programs. Many are easy to learn and powerful.

There are potential security trade-offs with the speed and facility that come with using an interpreted language. Interpreted languages do not come with the up-front benefits of program correctness, type checking, and security policy verification that compiled languages do. Securing interpreted languages requires layering extra efforts to the development done in the interpreted language, including automated and comprehensive testing, scanning, security testing, and code reviews. These practices are all part of the security of CISSP software development methodologies; however, interpreted languages increase the necessity of their use. However, even with the best testing, there’s no guarantee that the low-level language aspects are correctly aligned without checking.

Type Checking

Regardless of the language used, all programs deal with data, and they generally distinguish data by categorizing it into different types. Each data type has formats, memory sizes, and conversion rules. All data types are not the same. For instance, an integer and a “string” are two different data types. These two data types have different underlying memory structures that require a translation when converting or comparing between them.

Type checking is the process of verifying and enforcing constraints of data types.

Type safety is the aspect of type checking that prohibits data stored in incompatible data types from being transferred from one data type to the other. Even assigning similar data types needs to be checked if their sizes do not match; after all, variables do have to live in memory. Trying to store a 4-byte field (long integer) into a 2-byte field (short integer) simply will not fit into the memory allocated, and it will overflow the space.

Type checking can occur either at compile time or at runtime. Type checking that happens at compile time is known as static type checking. Type checking that occurs at runtime is known as dynamic type checking.

  • Some languages have type ambiguity. Some scripting languages interpret the value null, 0, and the empty string, all as being false. This is a potential cause of logic or program errors.Static type checking is when a programming language knows the data type of variables at compile The data type can be either specified in code or derived by type inference. Static type checking is done by the compiler, and therefore bugs related to incompatible data types can be caught in the compile stage.
  • Dynamic type checking determines the data type based on the runtime values of variables and not by any specified data type.

Some languages have type ambiguity. Some scripting languages interpret the value null, 0, and the empty string, all as being false. This is a potential cause of logic or program errors.

Language Generations

CISSP development methodologies in this explain computer languages have come a long way since the early 1940s and the first general- purpose digital electronic computer, the Electronic Numerical Integrator and Computer (ENIAC). There are five generations of computer languages:

  • 1GL: This first-generation language is machine code. Machine code is a binary series of ones and zeros that the machine would read and run directly. Because it was machine code, it was specific to the computer and couldn’t be ported to other computers. Machine code is complicated to edit and update. The code was installed on the computer via punch cards, punch tape, or by setting switches.
  • 2GL: Assembly language is the second-generation programming language (2GL). Mnemonic labels in place of binary machine instructions made assembly more accessible for the programmer to use.
  • 3GL: Third-generation programming languages (3GL) are the general-purpose programming languages that developers use. 3GLs introduce conditional statements, looping structures, expanded label naming, structures, and classes. Third-generation programming languages are significantly more useful and powerful for the programmer. Another 3GL improvement is that the code became machine independent. Interpreters and compilers stepped into the role of translating 3GLs into machine code. They also enabled structured programming and object-oriented programming. Examples of 3GLs are Fortran, COBOL, C, C++, and Java.
  • 4GL: Fourth-generation languages (4GL) are designed to build specific programs. 4GLs are considered to be a subset of domain-specific languages, which are com- puter languages that are specialized to a particular domain. Some examples of the domains that 4GLs inhabit are database management, web development, GUI development, and report generation. Examples of 4GLs are the Structured Query Language (SQL), ColdFusion Markup Language (CFML), XML User Interface Language (XUL), and Oracle Reoprt.
  • 5GL: A fifth-generation programming language (5GL) is designed to solve problems independent of the programmer providing the logic. Fifth-generation languages execute and solve problems based on information provided them. 5GLs are mainly used in artificial intelligence Prolog is an example of a 5GL.

The higher the level of a language the greater its level of abstraction and the more complex its systems interactions. Understanding the level of language can be useful when considering code review and similar security-related concerns.

Programming Paradigms

CISSP development methodologies in this explain different styles of programming give programmers a variety of different strategies and tools to solve the problems for which they write the code. It is important for a security professional to be familiar with these paradigms to be able to infer the security benefits or the impact of its use.

  • Imperative: Imperative programming is a paradigm that describes how a program It does this by using an explicit sequence of statements that update the state of a program. Program correctness, or how well the program executes its logic to satisfy its purpose, depends upon the sequence of its code. In the imperative programming paradigm, security comes in both the correctness of logic and how secure coding patterns and idioms are insinuated in the program’s logical flow.
  • Procedural: Procedural programming languages group common logic together in functions, enhancing their modularity and Programs then access that functionality using procedure calls. Security in the procedural paradigm     is similar to imperative programming in that the structure and how security is embedded in the software structure are important. Of particular concern in procedural programming is how well the software logic is decomposed into functions. How this is done is beyond the scope of this book, but the specificity of logic and the number of lines of code in the functions affects its inherent risk to the overall program by affecting the complexity, maintainability, and defect likelihood within its code.
  • Declarative: Declarative programming describes what a program should do and not how it should do it. Declarative languages such as Prolog or SQL let the programmer code by specifying the desired result. Although declarative programming removes the details of how the result is obtained, that does not mean it is without security considerations. Input validation and sanitization is a security concern that should be layered onto the declarative programming environmnt.
  • Logic: Logic programming is also known as rule based and is a paradigm based on specifying a set of facts and rules in a knowledge base. An engine infers the answers based on the outcome of the relationships between the facts and rules. Security in the logic programming environment should concentrate on input validation and sanitization as well as minimizing program defects. However, another security consideration is the languages that implement logic programming. These languages weren’t necessarily created for general-purpose commercial use.
  • Symbolic: Symbolic programming is a paradigm in which the program can manipulate its own source code to create new functions and logic, giving it advantages in expressivity. Symbolic languages are powerful in their ability to rewrite themselves. Security in the symbolic programming environment should concentrate on input validation and sanitization as well as minimizing program defect.
  • Object-oriented: Object-oriented programming abstractly models the environment and software requirements into separate objects that communicate with each other. Objects maintain an encapsulated internal state that is hidden from   the external environment. Because encapsulation hides the internal state of a program from the environment, it is not always evident what effect changes to the internal state have on the program correctness. Testing the internal state is challenging because it is not directly accessible to test from the environment external to the object. One positive aspect of object-oriented programming is that objects have rules that can be used to enhance security. For example, a rule could be   used to limit specific transformations of data.
  • Functional: Functional programming is a declarative type of programming paradigm based on composing pure function Pure functions are those that always return the same value for the same input. Unlike object-oriented programming, functional programming avoids maintaining a shared state and mutable data. These, along with other qualities, make functional programming more predictable and easier to test than other CISSP development methodologies. These qualities of functional programming support secure software. Predictable and testable software is more likely to be secure software.
  • Aspect-oriented: Aspect-oriented programming separates business functionality from other types of software concerns such as logging, authorization, data validity, and transactions. These separate, nonbusiness-related software concerns are known as cross-cutting concerns. These cross-cutting concerns can then be applied transparently as a layer to the business functionality software in a process often referred to as weaving. Being able to separate out such important but nonbusiness functionality makes for cleaner and more maintainable code, which supports the software’s security. Furthermore, as cross-cutting concerns, se