As a security consultant years ago, clients would typically call me to do a pentest or vulnerability assessment of their products before they went into production or to assess products already in production. One of the things I found was that there usually was no security review (design reviews or security testing) that had been done before I got into the picture. In cases where we had a client with multiple products, several engagements over time showed that they had the same problems come up repeatedly. I then started thinking about how to do things better. The obvious answer was to incorporate security early in the SDLC. But this is easier said than done.
Being a consultant, it was easy for me to ask clients to incorporate security early. I would show graphs and charts from published research about how doing it right the first time was better and less expensive than doing it later. You tend to spend more, your fixes may not be comprehensive because you have to work with existing architecture or infrastructure. While I could go on about why incorporating security earlier was better, I had never done it myself and I started wondering how I would do it.
I got my chance soon enough. After some trial and error, I proved to myself that it could be done and that it was really better. I used to call this process “early engagement model” but now there is a way cooler term “shift left” which is basically the same thing, but seems new. Basically, it means moving the security activities to earlier stages in the SDLC.
The following figure shows the different stages of SDLC:
Most people usually start at the requirements stage, but I am going to add a stage before that. As we will see later, this is a crucial addition to shifting security left.
The Planning stage will let us do preparatory work that will help keep all the other stages on track. I shall go over each stage in the rest of this article.
I call it planning stage, but it is basically a stage before we start doing anything with system development. This stage helps set the security direction. The primary activities in this stage will be defining the organizations’ security standards and training. By defining security standards and codifying them, you provide a reference to everyone in the organization and they can use this to guide them.
For instance, server build standards will help you consistently deliver hardened servers on demand. Secure coding standards provide a guide to developers on the principles they need to follow. Cryptograpy standards define the algorithms and key strengths required for different purposes and also defines when hashing should be used as opposed to encryption. The organization can have a whole lot of different covering areas such as desktop configuration, key management, configurations for different Operating Systems, Operating procedures, Release Management Processes, etc. The data classification standard is very important since that will dictate the sensitivity of different kinds of data and how you protect them.
Now that you have the standards defined, the appropriate teams need to be aware of the standards relevant to their areas of work. This may include training developers on secure coding practices, using developer security testing tools, or training the teams responsible for server builds on hardening the server configurations. This stage is critical. The amount of effort you put into the training stage will be inversely proportional to the amount of security defects you find in subsequent stages.
You also need to understand what regulatory requirements apply to your organization and ensure that all the relevant teams are aware of them. For example, there may be cross border data sharing restrictions, PCI will apply if you handle card holder data, GDPR will apply if you have European citizens as customers. Being aware of these requirements incorporating them early will help you build systems right the first time, without the need to retrofit later on.
All organizations, when they start development of a product, will have functional requirements. But they do not usually include security requirements. For instance, if PCI applies, you cannot store PINs and Card Numbers must be rendered unreadable anywhere they are stored. This might require strong encryption (one of the ways of making them unreadable) or you may want to reduce PCI scope by using a tokenization service. But knowing that you need to protect card numbers from the outset and making it a requirement will ensure that you do it right from the beginning.What are your data retention requirements?
I have seen multiple organizations struggle with complying with such requirements after the product is built. While I have used PCI as an example, this applies to all types of industry and regulatory requirements. One country you may operate in may have restrictions on who can view their citizens’ data or where the data can be stored or reporting requirements on the data. Documenting these requirements will ensure that you can later test and validate that these requirements are met. At this stage, you will have to ensure that the functional and security requirements comply with the standards that you have defined.
As you are planning out your architecture design, you may need to incorporate any storage requirements (regulatory requirements on storage location). If one of the countries you operate in requires data to be stored in-country, you will need to consider a Data Center in that country. This may, in turn, impact the overall performance of your product.
You also need to define authentication requirements. For instance, some countries have specific requirements on what biometric authentication can be used for while other countries may be more liberal. You will also need to define the access control levels for your product. Are all users the same, are there different levels of users, can the product users themselves define the access control levels for other users, is it going to be role based, resource based, claims based?
You also need to define whether you are going to combine combine customer data in the database and logically compartmentalize them, how are administrative functions accessed. WIll they be part of the same interface or will there be a separate interface that is only accessible internally? Will you be using an HSM for encryption and key management, where will it be placed in the network?
The above is not a comprehensive list, but these need to be documented as detailed design or user stories to ensure that the developers can translate all that accurately into code.
Defense in Depth
This essentially means that you should not depend on a single control to protect against attacks. For instance, If you are only relying on your perimeter firewall to keep intruders out, but have not hardened servers, implemented the principle of least privilege, segmented your network, etc, if your firewall fails, an attacker will have a field day within your network. Another use case may be that you may want to consider re-authenticating the user for any sensitive activities. You have to make sure that even if one control is breached, it is still difficult for an attacker to cause damage.
Principle of Least Privilege
Ensure that all access is only to resources or functions that are the minimum necessary for the person to perform their function. For instance, do not allow root privileges for application accounts. Tailor your roles to ensure that there are no superfluous privileges. This will help contain the damage in the event of a breach.
Isolate your Core Services
The idea here is to ensure that even in the event of a significant attack, you are able to run the most important functions of your product or infrastructure. You may select the core functions based on how critical they are or how much they are used. This also involves making sure that you have audit trails, and recovery built into the design.
Wikipedia defines Threat Modeling as “a process by which potential threats can be identified, enumerated and prioritized – all from a hypothetical attacker’s point of view”.
At the design stage, you should build a threat model. This has a few benefits such as showing you potential problem areas in the design. If you find threats without sufficient controls, you may want to feed that back into your standards and training. You will also need to make decisions on whether you want to meet your deadlines and leave some threats without some controls or whether you want to take the time to address them appropriately. It is important that you ensure adequate controls are present rather than leaving them to be addressed later. Remember, we are trying to shift security left.
The most important things to remember at this stage is to constantly test the code as it is being written. There are open-source and commercial tools that allow developers to analyze their code for security issues. Use them to validate that the code meets the security standards and security requirements that you have defined.
With a lot of developers using external libraries, it is important that you scan them before using them in your code. I have seen a lot of applications use older versions of libraries. Make sure that you keep the libraries current to ensure you ahve incorporated the latest bug fixes.
An important task in this phase is to collect metrics on the security defects that you see. This phase will potentially generate the largest number of issues and by analyzing them, you can focus your secure developer training on the areas that have the most issues. Over time, the goal is to reduce the number and severity of the issues you see at this stage. And with the right feedback process, that will happen.
If you have done your Threat Modeling at the design stage and testing at the coding stage, this stage shoud not cause any concerns. That does not mean that you will not find any issues. You will still need to do Dynamic application testing to uncover any issues with integrating different part of the code, privilege escalation issues, etc. You should be testing the server configurations as well.
There should not be any major issues that come up at this stage. If they do, you should fix them immediately and adjust your security requirements/standards to ensure that you do not repeat them.
Personally, I do not like to be surprised with significant issues close to release. That is why I work very closely with developer teams and different security teams to ensure that problems are addressed as they arise.
Another thing to keep in mind is that as the release date nears, the pressue to overlook security issues or fix them later will increase. By setting expectations ahead of time, you can avoid some of that tension. When the business and IT teams know from the beginning that you will not let issues through to production, it will be easier to take a tougher line close to the release.
Even with all these, you will find that there are issues that pop up and you have to go to production without fixing them. I always take the stance that any issue, regardless of severity, must have a near term remediation plan. The most important thing here is to ensure that you track these issues to completion. Otherwise, you will end up with a risk register that keeps growing.
When you deploy your application, you need to ensure that you have a release management process. Have you ensured that the code that has been tested and certified is what is being released into production? Do you digitally sign your code? Does the production server configuration comply with the security requirements and standards? Have you tested the TLS configuration to ensure that the right protocols and ciphers are supported, the certificate is valid and from a recognized CA? Are the server headers configured correctly? You would have already performed a lot of these tests, but this is a final sanity check to ensure that everything is still fine.
You should also do production verification testing (PVT) to ensure that your product meets all requirements and works as it should.
Collect metrics on issues and feed that back into your security requirements/standards and processes.
Once the product is deployed and is available for use, you should perform regular testing. The reason is that new security vulnerabilities are reported almost every day and you have to make sure that your product as a whole (infrastructure and code) continue to be secure.
Depending on the industry, you may have regulatory requirements on 3rd party penetration tests. Even if you don’t, you should bring in 3rd party vendors to do pentests to identify issues your security teams may not have unearthed.
Findings should be reviewed and remediated, with any adjustments to your security requirements/standards done as appropriate.
Your ideal security program may look something like this:
By constantly testing, collecting metrics and fixing issues from the beginning, you will bake in security into the product from a very early stage. You should end up with a product that does not have significant issues. A major benefit will be that your teams learn to build secure products and do things right the first time.