In my previous post, I wrote about a simple process for triaging vulnerabilities across applications. Once you have the issues prioritized, the vulnerability remediation process is pretty straightforward. You don’t have a lot of options; either remediate the issue, ignore it, or apply other measures (compensating controls) to mitigate the risk posed by the vulnerability.
1. Rip and Replace
This is the most common approach taken. Essentially, you are going to fix the problem by “amputating” the vulnerable component and replacing it with a component that fixes the vulnerability (either directly or by using a different open source project). If you’re going to replace the component with another version, however, you need to be sure that you’re not jumping from the frying pan into the fire.
Let me explain. Our report on open source in commercial applications found that the average vulnerability in open source components used in commercial applications was over five years old. In other words, the vulnerability was first publicly disclosed over five years prior to our analysis of the commercial application using that component. If I replace that with a component that fixes those 5-year-old vulnerabilities, I’m probably replacing it with a component that is 4.5 years old, and contains more or worse vulnerabilities. Run another scan, and you’re going to see new vulnerabilities in the component. Instead, you need to look for information on the vulnerabilities in all versions of the components.
The chart to the right is taken from Black Duck’s public facing OpenHub. Looking up a component in OpenHub provides information on the number and type of vulnerabilities. You can use this to determine which version you want to switch to, and decide whether to stay within a major version, or switch versions. The latter choice may provide fewer security issues, but this needs to be weighed against your risk appetite and the level of effort required to switch versions when changes to the APIs may complicate code refactoring.
At some point, continuing security issues or a declining level of support from the open source community may spur you to look for similar components. In this case, OpenHub provides a list of similar projects, as rated by the OpenHub community of over 300,000 users.
At times, a vulnerability will be isolated and require changes to only a few lines of code. In those cases, the open source community may issue a patch to remediate the issue. When available, this option makes vulnerability remediation a relatively simple task.
We see a formal patch issued most often in Linux distributions. While applying a patch or rewriting the code yourself can be less disruptive in the short term, you also need to consider maintainability of the component. Rewriting the code essentially results in you branching the project, and you have to assess whether this is something for which you want to take on long-term responsibility.
There are circumstances when doing nothing is the right decision. This is typically the case when the vulnerability has a low CVSS score and a non-public facing interface. In those cases, the risk posed by the vulnerability may be deemed acceptable by the business. Another example could be that the vulnerability is not reachable. In many open source components, the feature set expands over the years. If the vulnerability is in functionality you aren’t using or that you can comment out, it becomes a non-issue.
Remember, absolute security doesn’t exist, and you probably don’t want to fix every vulnerability. The goal of security is to support business goals and reduce risk to an acceptable level (residual risk is inevitable).
4. Apply Compensating Controls
Finally, we come to compensating controls. Think of these as activities we can take in lieu of replacing the vulnerable code by reducing risk to an acceptable level. Additionally, we may decide to fix the vulnerability but can’t do so for 90 days due to development schedules or the complexity of the fix. In those cases, we need to mitigate the risk posed by a vulnerability until you can fix the vulnerability.
How? You need information about the vulnerability and likely attack vectors. For example, there may be rules for your IDS or IPS that can alert you, or WAF rules that can block the attack. If you execute the exploit in a test environment, you can generate data on what to look for in your SIEM. You may even find that the compensating controls you implement mitigate the risk to an acceptable level for your organization, and eliminate the need for vulnerability remediation in this case.
Finally, in many cases, understanding the artifacts generated by the exploit are a good practice regardless of how quickly you can remediate a vulnerability. Remember that these vulnerabilities have often been in the code base for years prior to public disclosure. Heartbleed, for example, was present in OpenSSL for over 2 years. ShellShock was present in Bash for 25 years! Just because a vulnerability that has been present for years was only disclosed recently, it's a mistake to believe that nobody had prior knowledge of the issue.
Wash, Rinse, Repeat
Application security requires constant diligence. Integrating tools like Black Duck into a CI/CD process allows early detection of security issues in the open source you use. Hourly updates to our KnowledgeBase provide you with information on new vulnerabilities in your code – without requiring rescanning.