Software Patterns and Frameworks
Developments having good designers know not to create from first principles. Good designers create designs from existing structures that have solved many of the functional and security problems.
A pattern is an abstract design solution to a recurring problem. The concept of software patterns comes from observed recurrences of problems found in developments software and a consistency in the solutions to these problems. The problems we mention here are not those of chasing down bugs or of original designs but those that are part of nearly every software product: the problems of creating data structures, managing programming behavior, enforcing correct procedures, and the like. Common solutions have been discovered to solve these problems.
A pattern is a design description of a solution to a repeated problem in a particular context. A pattern’s context is a description of the situation to which the pattern can be applied to solve the problems that define its existence. A pattern’s context describes the various participants, their goals, and their limitations and constraints to achieving their goals.
The concept of a pattern is not limited to the software design level. It can exist at the software architecture or even enterprise architecture level. Two key elements make a design a pattern: the reusability of the design and the general applicability of the design to similar contexts.
Software frameworks often implement one or more software patterns for general use. A software framework is a software implementation of patterns. As patterns are abstract reusable solutions, frameworks can be used in creating the code for a solution to a software problem.
Design Patterns
A design pattern is a reusable solution developed to solve a particular common problem. A design pattern is not a completed design but rather a template or written document that can be applied to solving a recurring problem during the process.
Before diving into the different types of design patterns, let’s review some concepts that are essential to understanding the topic. The topic of design patterns had primarily come through the object-oriented paradigm of design and programming software systems. Object orientation models program structures on what would be analogous to what one would find in the real world. Programs are composed of different structures, with each structure having its own data and behaviors that are defined for a specific purpose and use in the program.
Program structures in this paradigm are referred to as either classes or objects. A class is the template of a program structure. At a high level, it can be considered to be a program structure’s blueprint. As a blueprint or template, a class is meant to become something to be used in a program. To use a class in a program, it becomes an object.
An object is a class that has memory allocated to it and data. This process of creating an object from a class is called instantiation.
Multithreaded programming and concurrency are other concepts to refresh before jumping into design patterns. Concurrency is when program code can execute multiple and distinct lines of logic simultaneously. To achieve concurrency, a program can use a concept of a “thread” of program logic. A thread in a program is both a program structure and facility to execute logic independently of the main execution of a program. Software that uses multiple threads is known as multithreaded programming, and it is a complex design and program resource management task. This is where design patterns come in as a way to reduce complexity and make repeatable the solutions to common design challenges.
There are four families of software design patterns:
- Creational patterns are for class instantiation. Types of creational patterns include Abstract Factory, Builder, Factory Method, Prototype, and Singleton.
- Structural patterns define relationships between objects or classes and include Adapter, Bridge, Composite, Decorator, Facade, Flyweight, and Proxy Pattern.
- Behavioral patterns define how classes and objects communicate. Types of behavioral patterns include Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, State, Strategy, Template Method, and Visitor.
- Concurrency patterns solve the common design challenges in multithreaded programming. Some examples of the concurrency patterns are Active Object, Balking, Proactor, and Reactor, as well as other.
Because of their emphasis on good design, all design patterns have a security impact. Software design patterns can aid in improving confidentiality, integrity, and availability.
For more sources of software design patterns, refer to the Portland Pattern Repository (http://c2.com/ppr/) and the Hillside Group (www.hillside.net/). The Hillside Group sponsors an annual Pattern Languages of Programs conference.
Security Patterns
A security software pattern is a solution to a recurring security problem that occurs in a specific security context presented in a generic formula. Software security patterns describe designs for the purpose of achieving a security goal. Security patterns are an effective means of collecting, describing, and communicating software security design concepts. The reference and use of security design patterns provide building blocks for secure software designs. Security software patterns help to:
- Reduce attack surface area
- Create secure settings by default
- Provide least privilege to users to carry out their job functions
- Establish controls in depth
- Ensure applications remain in a secure state if they fail
- Separate the duties of users
The growth of security patterns interest and developments came about in the late 1990s, with a significant expansion in the 2000s. The Jul/Aug 2007 IEEE Software Special Issue on Software Patterns featured an article by Munawar Hafiz, Paul Adamczyk, and Ralph Johnson called “Organizing Security Patterns” that collected and classified the body of existing security patterns. The article describes how security patterns can be aligned with the context of target applications, organized by STRIDE threat model categories, and with pattern language examples describing relationships among multiple security patterns working together.
This material organizes patterns around here are three areas of concern: application, the application’s perimeter, and those related to the exterior environment. Application-oriented patterns are known as core patterns, as they apply to the core of the application. Application perimeter patterns are concerned with security issues at trust boundaries between the application and other trust environments. Exterior security patterns cover security concerns surrounding the application domain and perimeter.
Some examples of security patterns organized in this system are demonstrated in Tables 8.2 through 8.4. As you can see, not every category has a security pattern. For a more exhaustive list of patterns, see Munawar Hafiz’s Security Pattern Catalog (http://www.munawarhafiz.com/securitypatterncatalog/index.php).
A discussion about software security patterns is not complete without mentioning cloud application security patterns. Cloud design patterns have been produced by a variety of sources, both vendor neutral and for and by the leading public cloud service providers.
Good patterns solve common problems in a context, and true to form, many of the cloud application pattern catalogs are organized around the typical challenges of cloud developments. Like the common design patterns, cloud patterns can have a positive impact on security because their use improves the confidentiality, integrity, and availability of cloud applications.
CloudPatterns.org (www.cloudpatterns.org) is a vendor-neutral cloud technology and patterns resource published on the Web. It has organized a pattern catalog into the following categories:
- Sharing, Scalability, and Elasticity
- Reliability, Resiliency, and Recovery
- Data Management and Storage Device Patterns
- Virtual Server and Hypervisor Connectivity and Management Patterns
- Monitoring, Provisioning, and Administration Patterns
- Cloud Service and Storage Security Patterns
- Network Security, Identity and Access Management, and Trust Assurance Patterns
CloudPatterns.org also defines compound cloud patterns. Compound cloud patterns are higher level, meta-cloud patterns that are composed of a number of more granular cloud patterns. Compound cloud patterns describe large-scale patterns such as the composition of the private cloud or a public cloud, among many other similarly sized cloud concerns such as software as a service, platform as a service, and infrastructure as a service. Compound cloud patterns also describes functional, behavioral, and compositional patterns of clouds such as elasticity, bursting, multitenancy, and workload management, to name a few.
For additional resources for cloud application and design patterns, see the sites of AWS (http://en.clouddesignpattern.org/index.php/Main_Page) and Microsoft (https://docs.microsoft.com/en-us/azure/architecture/patterns/).
Model View Controller
The Model View Controller (MVC) pattern is an example of an intersection of both a design pattern and a security pattern. It is used in languages such as Java, C#, C++, Ruby, and Python. Some of the most popular software frameworks to implement the MVC pattern are Java Struts, Spring MVC, Ruby on Rails, and Python Django. MVC is a popular software architectural pattern used for the developments of web applications.
MVC divides an application into three layers: the model, the view, and the controller. The model separates the application’s representation and storage of data. The view controls the presentation of data. The controller encapsulates and directs the business logic of data. It also serves as a bridge between the model and the view.
MVC is a security pattern for many reasons. MVC’s layering of presentation, logic, and data allows for the implementation of appropriate security controls and security patterns at each layer. Authentication, account lockout, and session management can be managed at the view layer. Access control can be enforced at the controller layer. Data inspection and sanitization, encryption, and access control can be enforced at the model layer. Additionally, cross-cutting security concerns such as secure error handling, secure logging, and communication can be implemented and contained at each layer.
MVC promotes good design practices that lead to higher-quality software implementations. MVC promotes cohesion, where program functionality is grouped into structures by similarity. Design implementations such as these improve software maintainability, reduce complexity, and promote code reuse, thus reducing the likelihood of software defects. MVC also promotes good design through low coupling of modules of code. Low coupling means that the software modules that make up the program are relatively independent of each other. Modular independence makes the developments and maintenance of a module less likely to have an impact on other modules.
Software Languages and Frameworks
Software frameworks are code platforms that contain generic code for developers to adapt and use. Software frameworks by their design are the implementation of one or more security or design patterns in its code. As such, software frameworks provide the code already composed that makes up these security and design patterns for the developers to customize and use. Developers often use application programming interfaces (APIs) to access a framework’s libraries when they develop software. A software framework increases the efficiency and productivity during new software development. Because soft- ware frameworks are implementations of software security and design patterns, their use improves the quality, robustness, and reliability of new software developments.
Software frameworks are most useful in providing the code that software developers need that offers most of the solution that they are looking to build. They save developers the time and effort of having to write the basic plumbing code essential to a good application.
Web application security is a common framework theme. Many frameworks such as Struts, Django, and Rails offer input validation, secure sessions support, XSS protection, and so forth. Software frameworks also offer communications facilities such as HTTP/S support, endpoint configuration, software patterns implementation, messaging, logging facilities, user interface developments, and security features that are essential to the com- position of an application.
Java
Since the mid-1990s, the Java language has been a popular language for business and academia. Java has had many features since its beginning, such as security, cryptography, graphical user interface, database connectivity, distributed computing, and multiprocessing capabilities. The Java language improves upon the security of other third-generation languages that had come before it.
Java has a robust error and exception handling framework. This framework handles buffer overflow problems, null pointer references, and many other code-related issues that otherwise would become security vulnerabilities.
Oracle provides the Secure Coding Guidelines for Java Standard Edition (www.oracle.com/technetwork/java/seccodeguide-139067.html).
These are a few of the many popular Java implementations:
- Java Enterprise Edition: Java Enterprise Edition is commonly used to develop e-commerce, information systems, or large-scale applications developments. Java Enterprise Edition’s security model is both declarative and Declarative security applies security layers to the application defined in project configuration or annotations on the source code. Programmatic security is writing security statements into the business logic code. The Java Enterprise Edition’s security vulnerabilities mainly consist of the classic vulnerabilities to which most applications are susceptible, the OWASP Top Ten. Vulnerabilities in the Java Runtime Environment affect the security of the Java Enterprise Edition.
- Struts: Struts is a free open-source framework for creating Java-based web applications, managed by the Apache Software It is an implementation of the MVC architecture pattern. The OWASP has organized the security features of Struts along the lines of the MVC pattern (https://www.owasp.org/index.php/Struts).
- Spring: Spring is an open-source developments framework that offers extensive infrastructure support for building high-performing Java applications efficiently and quickly and is sponsored and maintained by Pivotal Software. Spring’s base platform has a number of security-promoting features. Spring’s model of dependency injection promotes good design through loose coupling of This improves code quality and therefore potentially reduces software flaws and vulnerabilities. Spring’s Aspect Oriented Programming enables flexibility in the application of security to code. Spring’s design allows easy security testing of your code. The Spring Security project adds many security features (https://projects.spring.io/spring-security/):
- A comprehensive security architecture
- Extensive authentication and authorization support
- Web security features
- Method-level access control
- Protection against many attacks
- Integration with the Spring MVC framework
.NET
Microsoft .NET, first released in 2002, is a free, open-source platform for building applications. Although it is a cross-platform framework, it runs primarily on the Windows operating system. It is a common developments platform. The .NET framework has features for software developments security.
.NET’s code access security (CAS) prevents code from being executed beyond its allowed permissions level on a machine. Evidence-based security determines the type of permissions to be allowed before any code is executed at runtime. For example, the verified identity of the software publisher can be used as a source of evidence. Role-based security utilizes the principles of authorization and authentication to determine the users to be allowed or denied access to system resources.
Although routinely updated by Microsoft, the .NET framework has a history of security vulnerabilities. The latest versions of the frameworks with better security features may not be available in older versions of Windows. Also, .NET code can be prone to reverse engineering, and a wide variety of tools work within the .NET environment to obfuscate the code and provide cryptographic protections and other methods to defeat this sort of attack.
The OWASP .NET Security Cheat Sheet (https://www.owasp.org/index.php/ .NET_Security_Cheat_Sheet) is a handy set of security references covering the .NET framework including data access, encryption, and other general security topics. It also has guidance for ASP.NET MVC, Windows forms, and Windows Communication Founda- tion (WCF).
Microsoft’s published security guidance (https://docs.microsoft.com/en-us/dotnet/standard/security/) comprehensively covers .NET as a platform and framework. It covers fundamental security concepts such as language type safety and authentication and authorization. It also focuses on role-based security aspects, the .NET cryptographic model, Windows Identity and .NET, and secure coding guidelines for both managed and unmanaged code.
Managed code runs inside the .NET Common Language Runtime (CLR). Code created outside of the .NET CLR, such as a library based on Win32 C++, is unmanaged code. The .NET CLR does not have control over the execution of unmanaged code, particularly its memory management. It exposes the system to any potential flaws or risks that may exist in the unmanaged code.
.NET applications are susceptible to common security vulnerabilities such as SQL injection and cross-site scripting. Some security vulnerabilities to prevent include the following:
- Code injection
- Command injection
- Connection string injection
- LDAP injection
- Resource injection
- Second order SQL injection
- UTF-7 cross-site scripting
- Path injection
A detailed explanation of these vulnerabilities is beyond the scope of this text. Vulnerabilities for Microsoft.net can be found in the Microsoft.net framework security section of the common vulnerabilities and exposures (CVE) database(https://www.cvedetails.com/vulnerability-list/vendor_id-26/product_id-2002/Microsoft-.net Framework.html)
Personal Home Page
Personal Home Page (PHP) is a server-side scripting language that was implemented in the C language in 1994. Although originally designed for web developments, it also can be used as a general-purpose language. The language is sponsored and maintained by Zend Technologies.
The PHP user communities foster a developments culture for developers to embrace secure developments practices. Some PHP frameworks protect web applications from the common security vulnerabilities, such as SQL injection and cross-site scripting, and offer error and exception handling support.
PHP has security vulnerabilities that the security professional should be aware of, one being how it supports unsafe implicit data conversions. When using PHP to develop large applications with sensitive security requirements, be aware of its vulnerabilities and compensate for them. As a security professional, you should focus on best practices to identify and reduce web application security issues when presented with PHP use.
For more information, see OWASP’s PHP Security Cheat Sheet (https://www.owasp .org/index.php/PHP_Security_Cheat_Sheet).
Python
Python is an interpreted, multiparadigm, general-purpose programming language, first released in 1991 and still widely used. Python and its frameworks are supported by a community of dedicated developers who take security vulnerabilities seriously and promptly institute proactive countermeasures. Python frameworks have several built-in security features that make them difficult to compromise.
Python’s design philosophy makes it a good choice as a secure programming language. Python emphasizes simplicity, readability, consistency, and good design. Because Python is an interpreted language, comprehensive testing is a cornerstone to discovering flaws in Python developments.
Mature Python-powered web frameworks have built-in security features such as HTTPS support, template systems, and models that secure, validate, and sanitize data. A security professional has two main responsibilities in this regard. First, ensure that Python frameworks with security features are being used for your organization’s Python-based software. Second, make sure these frameworks’ configuration settings and security features are implemented in a manner that meets the risk and control requirements for the application software of which it is a part. Although research into the frameworks and auditing the software can take you far toward these ends, consider partnering with the software developments and architects to comprehensively achieve these objectives.
Ruby
The Ruby language is an interpreted, open-source, object-oriented general-purpose language developed in the mid-1990s. It is a popular programming language, with many developers favoring its dynamic and highly expressive nature. The web application framework Ruby on Rails brought the language into a mainstream developments consciousness.
Ruby frameworks have features that support software developments security. They have built-in features for safeguarding applications from input validation weaknesses and other web-based attacks. Ruby supports meta-programming, where security practices can be injected into code. Ruby’s syntax is favored by many developers to create clean, uncluttered, and secure code. Security information on the Ruby language, including common vulnerabilities and exposures, can be found at https://www.ruby-lang.org/ en/security/.
One popular example of Ruby is Ruby on Rails. Released in 2005, Ruby on Rails is a Ruby-based web application framework that is designed for developers to create data- base-driven applications.
Ruby on Rails prevents SQL injection attacks with a built-in feature for escaping specific harmful SQL characters.
Ruby on Rails provides helper methods that offer protection against cross-site scripting attacks. It has conventions for implementing security, and it is an extensible framework allowing integrations with third-party features to enhance the application’s security.
The OWASP has a cheat sheet of Ruby on Rails security vulnerabilities at
https://www.owasp.org/index.php/Ruby_on_Rails_Cheatsheet.
JavaScript
JavaScript is an interpreted, high-level, weakly typed, multiparadigm programming language. Despite its name, it is a completely different language from Java. Along with HTML and CSS, JavaScript is one of the three core languages of the web browser.
Despite that it is best known as a browser scripting language, JavaScript has found a place in nonbrowser environments, such as the language of choice for Node.js.
JavaScript has a number of vulnerabilities. Common JavaScript vulnerabilities relate to its use on the client side. JavaScript can be susceptible to cross-site scripting and cross- site request forgery.
There are two significant factors contributing to JavaScript vulnerabilities. The first is that it is an essential and interpreted language in the browser, and thus the implementations may vary. The second and even more significant factor contributing to JavaScript vulnerabilities is the poor management of libraries used by JavaScript frameworks.
Two areas that a security practitioner should focus their attention on when evaluating JavaScript frameworks are the following:
- At least one library contains a known vulnerability.
- The library packages used are out of date with the current release, possibly on the order of years behind.
These are significant issues for many web applications that use JavaScript frameworks.
JavaScript vulnerability reporting is not organized as that of other languages is.
There is no single consistent source of documenting JavaScript libraries’ vulnerabilities or their effects.
Also, when you consider that the proliferation of newer JavaScript frameworks may not have been sufficiently tested for security weaknesses, with their code visible as open-source, these frameworks can be targets for security attacks, and thus it is a best practice to exercise caution and thoroughly evaluate JavaScript libraries prior to their use.
JavaScript can be disabled on the client side.
One popular example of JavaScript is Node.js. The Node.js framework was released in 2009 as a runtime environment for running JavaScript code on the server side. It is a single-threaded, event-driven, nonblocking Input/Output (IO) that allows for simultaneous handling of requests that results in great scalability. Node.js on the server shares similar structures with client-side code, both being JavaScript, which makes it easier to integrate security practices into web applications. An emphasis on JavaScript on both the client side and the server side brings with it the advantages of a concentration of language expertise as well as shared language productivity and security tooling. These combined factors improve secure coding practices. The code can be deployed quickly as well, allowing for faster bug and vulnerability fixes. This speed of responsibility is an effective risk management technique.
Node.js has security vulnerabilities. In October 2017, nodejs.org reported a high severity denial-of-service vulnerability due to changes in one of its dependen- cies. Fortunately, Node.js vulnerabilities are reported as CVEs and are hosted by MITRE at https://www.cvedetails.com/vulnerability-list/vendor_id-12113/ product_id-30764/.
For information on how to report a Node.js security vulnerability or how to be informed of Node.js vulnerabilities, see https://nodejs.org/en/security/.
Becoming and staying informed about Node.js security vulnerabilities is half of the picture to securely using the framework. It is just as important to make sure that you are keeping its libraries up to date, particularly when the Node.js reference material tells you to do so.
The functionality of the Node.js framework consists of software libraries known as packages. These packages are installed and managed via the Node Package Manager, more commonly known as npm. A significant Node.js security concern is that npm can be exploited for malware distribution. When using npm, make sure that the npm library name is correct, inspect the source code, and install it safely with –ignore-scripts.
Include a security source code inspection of the code in the Node.js packages your organization uses. Not all Node.js package source code meets secure coding standards, so the packages are a source of vulnerabilities in applications that use them.