Part 2: A Vulnerability Is Often Just the Beginning
When we identify a security issue, it’s natural to focus on the bug itself: what is vulnerable, how it can be exploited, and how to fix it. These are important questions, of course, but they don’t tell us how bad the consequences could be. For that, we need to understand the application, its permissions, the data it handles, and what an attacker might be able to do after exploiting the weakness.
That’s a useful distinction to make when assessing risk. A vulnerability can be an isolated problem with limited consequences, or it can become the starting point for a broader compromise. The same type of vulnerability can present very different levels of risk depending on the surrounding context.
Where vulnerabilities come from
In general, we can think about two sources of application security issues: weaknesses introduced through our own implementation or design, and vulnerabilities that come from third-party code.
Our own code can introduce problems through incorrect input handling, missing authorization checks, misconfigurations, or mistakes in business logic - to mention a few examples. Sometimes the issue is deeper than a specific line of code. Complexity, unclear trust boundaries, or the way components depend on one another can create unsafe conditions that are difficult to see and easy to misuse. In these cases, the team introduces the weakness directly, whether through a mistake, an omission, or a design decision whose security consequences were not fully understood.
Third-party dependencies are a different source. We rely on libraries and frameworks for HTTP handling, database access, serialization, authentication, and many other functions, and those components can contain vulnerabilities of their own. Public advisories and CVE records help us track many of these issues, while severity scoring provides a common reference for their technical characteristics. Dependency risk also depends on how quickly we can apply fixes and whether a vulnerability is known before a patch is available. A newly disclosed issue may leave a short window for remediation, while a zero-day can require temporary mitigations before a vendor fix exists.
How bad can it get?
A useful part of risk assessment is considering what an attacker could gain and where that access might lead. A few familiar examples help illustrate why the immediate behavior of a vulnerability doesn’t necessarily represent its full impact:
- Cross-site scripting (XSS): Executing JavaScript in another user’s browser might initially do nothing more than display an alert pop-up, but depending on the application’s session design and other security controls, the same vulnerability could allow an attacker to perform actions as that user or even hijack their session. The affected page, the user’s privileges, and browser protections help determine how far the attack can go.
- Server-side request forgery (SSRF): A callback that merely reaches an attacker-controlled server may confirm that SSRF exists, but the same capability could reach internal services or cloud metadata endpoints. If the response exposes credentials, those credentials might allow access to other services or a storage bucket containing sensitive data.
- XML external entity (XXE): An XML parser configured to resolve external entities may expose a local file or reach an internal service. The impact could be limited to a harmless file read, or it could reveal credentials that enable access to other systems.
- SQL injection: A simple test such as
1=1may only reveal an error or confirm that input reaches a query, but a more serious case could allow an attacker to download an entire database. The database account’s permissions, query construction, and available application functionality help determine the impact. - Secrets in source code: A credential committed to a repository may appear to be a source-control hygiene issue, but if the credential remains valid, an attacker who obtains the repository could use it to access cloud resources, production systems, or sensitive data.
These examples show the difference between an initial signal and a possible outcome. They are possibilities, not guaranteed results. Knowing the vulnerability category is a starting point; understanding the actual deployment and its security boundaries is what makes the assessment useful.
From initial access to a broader compromise
In some incidents, exploiting a vulnerability provides initial access to an account, application, or host. From there, an attacker may try to maintain that access (persistence), obtain more permissions (privilege escalation), or use the compromised system to access others (lateral movement). In real-world compromises, achieving these objectives may involve chaining multiple weaknesses rather than exploiting a single vulnerability.
We shouldn’t think of these as a sequence that every attacker follows. Someone who can directly download sensitive records through SQL injection may already have achieved their objective. In another situation, an attacker who compromises a service with broad cloud permissions could reach resources well beyond the service itself.
The questions that matter are practical: Which credentials and permissions are available to the compromised component? What can it communicate with? Can an attacker change or create identities, deploy software, or maintain access after the original bug is fixed? These are the details that connect a technical finding to a realistic assessment of risk.
Limiting the consequences
When we understand the possible attack path, we can also identify which boundaries might prevent an initial problem from becoming a larger incident. Least-privilege identities, isolation between workloads, network segmentation, and restricted service-to-service access can all limit what a compromised component is able to reach.
Perimeter protections still have a role, especially in reducing unnecessary exposure, but they can’t be our only defense. It can be tempting to dismiss a vulnerability in an internal service because it isn’t directly exposed to the internet. That isolation reduces exposure, but it doesn’t guarantee the service will remain unreachable. An attacker who compromises another component or a legitimate identity may still be able to reach it. That’s why hardening needs to cover the application, identities, network, and infrastructure. This is the principle of defense in depth: if one layer fails, other controls can still help contain the attack and reduce its blast radius.
We won’t eliminate every vulnerability. What we can do is make more informed decisions about their consequences and design systems where one failure doesn’t automatically open the door to everything around it.
AI assistance acknowledgment: This post was written with AI support for paragraph construction, organization, and reviewing sentence clarity and arguments. The ideas, experiences described, perspective, and editorial decisions remain with the author.