Naming without Knowing: On Being Vulnerable

This is the second in a series about how we describe vulnerabilities and why it matters. Vulnerability records succeed at creating a shared name, but the data associated with that name are too coarse to reflect patterns of exploitation or defenders’ priorities. We have spent over 27 years now naming vulnerabilities without knowing exactly what they are.This series is about closing that gap.

I had all sorts of good  intentions to make this second post about the existing definitions for what a vulnerability is within cyber security. I have meticulously collected 67 unique definitions from academic publications, standards, government guidance, operational databases and various industry sources. Looking at the entire corpus of definitions like that has been really interesting. Like most “not-built-here” people, I think I could do better, but honestly, we have all of the essential building blocks to talk about vulnerabilities more precisely, we are just off in the emphasis and framing of what we are trying to describe when we talk about vulnerabilities.

To dive right in, think through these three statements: 

  1. The system has a coding flaw (think CWE).

  2. The system has a vulnerability.

  3. The system is vulnerable

Are these functionally the same? Is it possible to have a weakness in the code that does not present a bigger problem (vulnerability)? Then is it possible to have an instance of a vulnerability present in the system but for some instance, not be vulnerable (to exploitation)?  I hope you answered yes to those questions. But on the off chance you answered no, read on (and I would suspect it’s just a disagreement in semantics of the words I chose rather than a reality). 

The difference in those three statements is where I think we have most of our disagreements about what a vulnerability is. These concepts often blur together depending on the situation but also across our experiences, perspectives and where our daily focus lies. From a security perspective, we tend to focus on the coding flaw (as does SAST scans). It doesn’t really matter whether or not it’s reachable or exploitable right now, it still exists and could be a concern soon or at some possible point in the future. Vulnerability scanners (classic + SCA) tend to focus on the second. You are running a version of something that is known to contain a vulnerability. But that leads to the third state in our list, where practitioners rightfully complain about (unverified) reachability and the false positive rates in the tools. Because practitioners (and red-teams) most often care about the exposure and risk, which means they want to identify and prioritize the systems that are actually vulnerable to exploitation and the capacity for security failures. 

The primary challenge here is that determining if a system is vulnerable requires the joining of two disparate sources of information. First and perhaps most obvious, we need the localized knowledge of system context. There is no way to determine if a vulnerability makes the system vulnerable without understanding the instance and environment. But second, and clearly less obvious, is that we need to know the conditions under which a vulnerability creates a vulnerable system. This concept is so important for defenders that it bears repeating, restating and pulling out of a paragraph, so the article-skimmers catch it: 

A system is vulnerable only where the vulnerability’s required conditions intersect with the system’s actual configuration and environment.

This seems like a “well, duh” statement when stated like this, but this is clearly not obvious, because I challenge you, right now, to answer this question: “what are the required conditions to exploit the php2shell vulnerabilities?” Because they are not in the CVE or NVD record and they are not included in any scanner output. They are generally not structured anywhere and require a deep understanding of the chain of events that lead to exploitation. For example, did you know that the best-documented path for CVE-2026-109618 depends on how PHP is connected to the web server? Apache mod_php continues into shutdown after an out-of-memory failure during request startup, allowing cleanup to encounter invalid state. Meanwhile, PHP-FPM terminates the failed child and breaks that exact path. The vulnerable PHP code and attacker input may be the same, but one implementation allows one attack while the other stops it. FPM may still expose other PHP2Shell paths, and that’s precisely the point. The PHP version tells you PHP contains a vulnerability but not if the system is vulnerable. Worse, there is no standard vulnerability record, field, or location for these required conditions. Everyone wanting to establish if the system itself is vulnerable must hope that the vendor or some other researcher chooses to include these detailed fragments somewhere. Then and only then, can you (and everyone else) find, reconcile, and reconstruct the exploitation chain themselves if you want to do this.

Does the Effort Exceed the Value?

This is a big question and worthy of a focused discussion in a future post. For now, I feel safe in saying that our vulnerability management practices evolved in a different world.  The first CVE was published in 1999. It took 17 years for the average 30-day rate of publication to exceed one an hour. When the CVE program celebrated their 25th anniversary (2 years ago), we were seeing one vulnerability published about every 15 minutes. And now, just two years after that anniversary we have a new vulnerability every 3 minutes. 

There has been a new vulnerability published every 3 minutes over the last 30 days. That is 5 times the work load compared to just two years ago.

If it’s true that remediation is cheap and easy for everyone, then yes, adding any complexity or resistance to publishing vulnerability information seems silly. But if that’s not true, and there’s some mixture of change management, testing, roll out and back out plans, then limited resources drive the need for assessments, analysis, coordination and scheduling, and so we must talk about the information we need for prioritization and/or automation. 

Assuming the choice is between adding data to the record or not is not the choice we have. The choice is between asking for the data in the vulnerability information or asking all of the downstream consumers to regenerate the data for themselves. In other words, do we ask the source of information for more information (that many of them already should have), or do we ask anyone who needs it to fend for themselves and rediscover the same information. And if they don’t have the time or they are unable to piece together the information, then defenders work within this information gap and pay for it in the form of wasted effort and missed prioritizations with little-to-no feedback on their process. To be fair though, it’s been this way since the beginning of vulnerability publications. The universal and necessary conditions to go from a vulnerability to being vulnerable should be captured once, as close as possible to the vulnerability’s discovery and analysis (which is already happening anyway), rather than reconstructed independently by every affected downstream organization.

“Can be Exploited”

Now back to the 67 definitions of “Vulnerability” I collected. When it comes to the state of “being vulnerable”, 47 use some explicit form of possibility: can, could or may. The specific phrase “can|could|may be exploited” appears directly in the definitions 30 times. While it seems like that phrase is communicating something important, it’s not. It is only communicating that there must be a conclusion about a possibility. “Can be exploited” is a checkbox-criteria for a vulnerability existing. Now I’m not saying that exploitability isn’t necessary here, but I am saying that there are a very wide range of ways something can be exploited, and I couldn’t find any vulnerability database that asks for it or has a method to communicate it reliably. 

I think this is one of the shortcomings in how we think about vulnerabilities today. “Can be exploited” is a threshold you must mentally leap over, perhaps by extraordinary means, and then you are rewarded with a CVE ID on your resume. You don’t have to document that path, you don’t have to establish that it requires a company to have an odd set of configurations enabled, or that it has several dependencies which all must be true before a vulnerability can make a system vulnerable. 

“Everything wrong with the CVE program”

CVE-2020-19909 is a good example of how the phrase “can be exploited” can itself be exploited. That CVE was published for the curl command-line tool because it accepted a retry delay in seconds and multiplied it by 1,000 to get the milliseconds. Given an absurdly large value, that calculation could overflow, causing ordinary builds to (typically) produce a short delay. But signed integer overflow is specifically “undefined” in C, the language specification does not restrict the result to this observed behavior. Among the consequences for CWE-190 (integer overflow) they list crashes, memory corruption, and even code execution. Code execution and memory corruption  is rather unlikely with the modern and common C compilers, but let’s follow this thread. Let’s assume in the worst case that a C compiler was used (and listed as part of the conditions) that somehow enables code execution. This coding flaw is only in the command line version, so in a typical use, a user would gain access to crash the process they started or to run any command from… the command line? 

As I just imagined it, CVE-2020-19909, with the conditions in a normal setup, does not present a vulnerability. BUT remember we have the option to simply imagine a world where it can be exploited. It needs to violate some security boundary, policy or property (depending on how you define the bad things after exploitation). So, In order to cause an unauthorized action (actor gains access to execute something on the system), the process to set the retry-delay must be separated from the execution of the curl command line. In other words, curl must be initiated by a trusted user who accepts and does not verify a retry-delay from an untrusted source. Which means the set of conditions needs to be explicit about that. In as much detail as I can muster, these are the conditions: 

  1. The system must have a curl instance (from the list of affected versions) compiled with a compiler that really mishandles integer overflows, it’d be nice if we could find evidence of this. 

  2. An application must present some interface, which intentionally does not allow untrusted users to execute code, and which is running with a privilege the users of the interface do not have access to.

  3. That application must allow the actor to submit the retry-delay value for curl and must not parse or validate the value. 

  4. That application then must execute a command line pass the retry-delay value to the command-line version 

  5. The user must spawn a process for the command-line version of curl and pass in specially crafted retry-delay value. 

  6. The system overflows the signed integer and either crashes, corrupts memory or enables execution on the system from an actor not authorized to do so. 

Is that a common or even a likely setup? No. No it’s not. Possible? Yes!  

We have found a path where it can be exploited causing a security failure. Now we can create a CVE. But nobody is asked to document those conditions. Defenders can generally only test if we have that vulnerability, not if its presence makes any of our installed curl instances vulnerable. Besides, even if we wanted to capture that in a CVE record (or OSV, or GHSA), there’s no field or section in the record to capture it. 

Yeah, but so what… 

While I had every intention to share all of the analysis I’ve done on our existing definitions and the shortcomings and ambiguity they carry into our practices. Our problems are not in our definitions, they are in our mental models, our language and the structure of our vulnerability records. Better and more clear definitions are helpful and essential, but they will change nothing. We, collectively, need to start asking some very tough questions and maybe, just maybe, start entertaining the idea that what we think a vulnerability is needs to shift a bit. We need to improve the precision in our language and clarify and hone our knowledge and expertise. We do not need to shift the whole world, just the “in group” of people researching, documenting, and attempting to communicate vulnerabilities to others in the “in group”. For everyone else, we still have CVSS. 


Next
Next

November 2026 CVE of the Month: Which of Adobe's 31 ColdFusion Fixes to Rush (CVE-2026-106616)