One of the many consequences of security incidents is the development of the business subject’s awareness that more resources should have probably been invested in security.
The seriousness of investing in security is then put on the agenda almost on its own, as it becomes clear that trouble, in the form of malicious actions, does not only happen to others.
Unfortunately, by then it may be too late of a reaction because certain security incidents can cause damage of such a scale that they can lead to the end of business within a couple of years due to the impossible recovery.
Until such critical moments, investing in security often acts as an additional effort and cost which added value is not easily observable on the end product or service. Software is a good example of this, since from the user’s perspective secure and insecure software behave the same. Moreover, insecure software is often easier to use because of the communication with the user in which it automatically assumes that the user is legitimate and benevolent, so there are no additional checks for executing the given tasks.
Because it is not wise to exclude uncertainty from the calculation and the fact that vulnerability patches are more expensive the later they are introduced, it is important to consider security before it becomes necessary.
With software, that thinking ideally means in every segment of development and implementation [1]. In theory, the classic software development life cycle (SDLC) follows 6 steps from the initial idea of a product or service to the final point of software maintenance through user feedback. This SDLC consists of planning, analysis, design, implementation, testing, and maintenance. Phase boundaries are not always clear or in the specified order, but every end product certainly containes them. The idea is to think about security at every step and perform control actions that prevent introducing vulnerabilities into the final product.
Figure 1. Security by stages of SDLC. [2]
Guided by this idea, already at the initial stage of creating ideas and potential alternative solutions, it is necessary to take security requirements into account. In the broadest sense, a security incident is an event in which some of the security requirements are no longer met. The basic security requirements/criteria are the often-mentioned triad of confidentiality-integrity-availability (eng. CIA), which is sometimes joined by nonrepudiation and authenticity.
Not all of the stated requirements are applicable in all situations, and therefore it is necessary in the initial stages of planning and analysis to find out which of the security requirements are applicable and in what relation are they to the user’s requirements. Determining the security requirements that the application must meet will determine the general direction of the security controls required.
In the next step, design, threat modeling is a logical addition to the design process. As the design outcome is often accompanied by a diagram of the architecture of the future system, that exact diagram is further needed to create a threat model. Threat modeling consists of analyzing interactions of elements within the system with to determine potential attack vectors and possible threats.
For this, it is necessary to determine which elements are allowed to trust each other, and for which interactions it is necessary to establish additional security controls. Based on the system architecture diagram, it is possible to determine the flow of critical information and which security controls will enable that flow to remain protected from unauthorized interception, alteration or interruption.
Figure 2. Information flow during user login. [3]
When it comes to implementing the software solution, we come to the next step in realizing secure software, which is the practice of writing secure code.
In the last ten years, there has been a proliferation of guidelines for writing secure code for most programming languages. There are plenty of guidelines and instructions on how to write secure code [4], which is generally reassuring for security, but in practice is just one more in a series of rules that developers need to follow.
Among other rules are the rules of clean/clear code, non-repetition, documentation, agreed formatting on a specific project etc. These rules are generally taken for granted and expected from programmers, but writing secure code is still not a standard.
The developer is responsible for adopting good security practices, while in the testing phase, these practices are further validated.
A solution that can relieve the burden of the programmer and partially automate the relief of the concern is static analysis of written code. There are various tools that, in addition to the usual static checking, take into account potential abuse of the implementation and give warnings if the project code shows indications of it.
The development phase, at this point, is closely related to the testing phase, which can also provide another instance of security feedback through an eventual code review or static analysis.
Finally, we come to the maintenance phase of the software, where we once again have the opportunity to strengthen the security of the application, this time by conducting penetration testing.
Pen tests can consume a lot of resources, especially time, but in the end, they can show clearly what an external attacker would have to do to get into the system.
The purpose of the pen test is to find vulnerabilities in the application and exploit them to prove weak security points. Today, this is most often carried out semi-automatically and in a guided manner by the use of pen test tools.
In the case of web applications, Zap is one open-source example of such a tool [5].
Zap is used by providing it where the data entry and request points are and then choosing what type of attacks to execute.
In principle, everything that is visible on the graphical interface of the web application can be bypassed while the calls sent to the server can be modified.
Zap and similar tools can expose vulnerabilities that arise only in production, so an initial and then periodic pen test would be desirable to secure applications.
Security must be woven into the very core of the system that is being built.
From planning, design, implementation, and maintenance, every step can introduce vulnerabilities into the system, so for secure software, the Croatian proverb “better prevent than treat” is especially true, because the cure for software is in most cases either too late or too expensive.
Author:
Tin Potz, Software Engineer
References
[1] Best security practices in SDLC, https://vulcan.io/blog/secure-sdlc-best-practices/
[2] Security by stages of the SDLC, Hudaib, A., AlShraideh, M., Surakhi, O., & Khanafseh, M. (2017). A survey on design methods for secure software development. Int. J. Comput. Technol, 16(7).
[3] Information flow during user login, https://owasp.org/www-community/Threat_Modeling_Process
[4] General Checklist of Secure Coding Practices, https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/stable-en/02-checklist/05-checklist
[5] Zap, an open-source tool for penetration testing of web applications, https://www.zaproxy.org/