Introduction to the foundations of software development against program threats (I)
This article is part of a series related to software development and security, from the basics and global concepts applied, to the more specific controls and techniques to deal with threats to the programs built.
There are multiple ways in which a program can fail and, in turn, many other ways in which these failures can be converted into security holes. As with most industries we know, it is generally better to focus on monitoring and enhancing preventive techniques than on actually fixing and mitigating the failure once it has occurred. Not only because of the great savings involved, but also because of the potential misfortunes that can be caused by exploiting such vulnerabilities or critical flaws. Similarly, in software engineering we have multiple techniques that influence the controls against the threats of the software built. Moreover, these can —and should— be promoted during all development cycles, from specification and design, through execution and testing, to the verification, maintenance and monitoring phases. Anyway, this problem is approached from a global perspective by software engineering, directly affecting software quality, which means all the processes and techniques that promote a correct software quality.
In this article we focus on the principles and techniques that address an adequate development control. The objective is none other than to detect and mitigate the problems encountered during the specification, design, construction or testing phases.
The collective nature of development and its phases
Although it may seem that the process of software engineering and development is a perfectly individual task —and we do not deny it for specific cases, all-rounder people and really experienced professionals—, generally the contribution of value and business competitiveness includes complex processes and needs great interrelationships, good orchestration and a high quality development execution. Of course, we are not talking about small applications, proof-of-concepts or personal side projects. We focus on building enterprise software that requires a lot of resources, months of execution and considerable costs. This is where the workgroup and collaborative effort comes into play, involving people with totally different capabilities who, efficiently combined and organized, are able to produce a functional, quality product.
In short, development requires a collective that is capable of:
- Specify the system. From the prospecting phase and requirements capture, to the elaboration of the use cases and functional modeling of the system.
- Design the system. Elaborating the architectural proposal, the modeling of the solution and the solution provided to the functional and non-functional requirements.
- System implementation. Starting from the previous phase, managing, combining and distributing the resources (material, abstract and human) for the construction of the solution.
- Verification and testing of the system. Ensuring that both the requirements and the execution are met based on the design and planning.
- System review. Verifying that the assets produced are consistent with the specifications and the designed models.
- System management. Estimating the existing resources and constraints in the project, in the execution stages and in the micro-tasks, as well as the estimation and evolution projections of the project.
- Maintain the system. Follow-up of the problems encountered, improvements, developments, changes needed and made, as well as the evaluation of their effects on the overall quality and functionality.
Each team is distinct, and the work dynamics and capabilities of each one are totally different, even more so when the management tasks vary. This combination greatly influences the success of the group and of each project they take on and execute.
It is important to remember that there are really sophisticated attacks that can generally only be avoided with a correct execution of the system, taking into account both security and usability from the design phase itself. This is a key factor that is not often considered, as software organizations favor functional aspects and design based only on customer needs, when the scope should be broadened. In most cases, they only address their business model and the use cases of the users of the system, and not the rest of the key aspects for the correct operation of the complete system and threat prevention. From our perspective, we recommend and place special emphasis on:
- Reuse security systems as long as they are kept under constant review, verification and maintenance.
- Adapt the system to security, not the other way around.
- Usability takes a lower priority than the vital need and requirement of security.
- Usability plays an important role in reducing system lock-in and inefficiency due to security.
- Design usability and security as a cohesive sub-system.
- Tools are not solutions.
- Invest in periodic code review and control, controlled attack suites, as well as system verification and monitoring.
- Invest more resources in the higher layers of the system. Architecture is decisive.
- The customer must be satisfied.
In the next part we will discuss the aspects of modularity, encapsulation and information hiding, among others. Little by little we will address the key aspects in the prevention of failures and security breaches during software development.