Skip to main content
Platform
Platform Overview How It Works
Solutions
AppSec Teams Platform Engineering Pricing Blog
Sign In Request Early Access
Attack path analysis practical introduction for AppSec teams
Back to blog

Attack path analysis: a practical introduction for AppSec teams

By Adrian De Gendt

Attack path analysis means different things depending on who is using the term. In cloud security tooling it often refers to IAM privilege escalation chains across AWS resources. In network security contexts it refers to lateral movement paths through host segments. In application security, where we spend our time, it means something more specific: the sequence of code-level and service-level steps an attacker can execute, starting from an entry point they can reach, ending at data or functionality they want to access.

Getting a working definition matters because the tooling you need to produce attack paths in each of those contexts is different, and the remediation decisions that follow are different. This post is about attack path analysis in the application context, which requires understanding your application's architecture as a traversable graph, not just its vulnerability inventory.

What an attack path actually is

An attack path in an application context is a sequence of nodes connected by traversable edges, starting at an entry node and ending at a target node. More concretely:

An entry node is a point where attacker-controlled data enters the application: an HTTP endpoint, a message queue consumer, a webhook handler, a file upload processor. "Attacker-controlled" is the key qualifier. Endpoints protected by authentication are not entry nodes for unauthenticated attackers, though they are entry nodes for authenticated-but-malicious users.

A target node is what the attacker is trying to reach: a database row containing PII, a credential store, an admin-only function, a service that has write access to production infrastructure. The sensitivity classification of target nodes is application-specific and has to be defined, usually based on data classification policies or threat model decisions.

An edge is a traversable step between nodes: a function call within a service, an inter-service HTTP call, a shared queue read, a file system access from one process to a shared mount. Edges in a microservice application span both code-level and service-level topology, which is why attack path analysis for microservices requires more than a traditional call graph.

A complete attack path runs from an entry node through one or more intermediate nodes to a target node, where every edge in the path is traversable given legal application inputs. That last qualifier matters: a path that requires an impossible combination of inputs is not a real attack path, even if the static graph shows a connection.

The graph construction problem

You cannot enumerate attack paths without a correct application graph. This is where most manual attack path analysis breaks down in practice. Teams draw architecture diagrams, but those diagrams capture the intended design, not the actual implementation. Service A is supposed to call Service B only through the public API, but the implementation has a legacy internal endpoint that Service A also calls. Service C is supposed to be read-only, but there is an undocumented write path that was added during an incident response and never removed.

Accurate graph construction requires combining multiple sources: static analysis of the codebase for in-process call relationships, dependency analysis for library boundaries, and service topology discovery for the inter-service graph. None of these alone is sufficient. Static analysis without service topology misses inter-service edges. Service topology without code-level analysis misses which endpoint handlers call which sensitive internal functions.

This is a solvable engineering problem, but it requires automation. Manual graph construction for a 20-service microservice application with active development is not maintainable. The graph changes with every deployment. An attack path that was unreachable yesterday may be reachable after today's deployment if a new endpoint was added that connects to an existing sensitive code path. Continuous automated graph construction is a prerequisite for useful attack path analysis at development velocity.

Path enumeration and path ranking

Once you have an accurate graph, enumerating attack paths is a graph traversal problem. Starting from each entry node, forward traversal through the graph identifies all target nodes reachable from that entry node, and the paths that connect them. This is computationally tractable for application-scale graphs, though it requires careful handling of cycles and service-to-service communication patterns that can create loops.

The output of enumeration is a set of paths, typically ranging from a handful to dozens depending on application complexity. Ranking those paths by risk requires combining several factors: the authentication requirement at the entry node (unauthenticated entry is higher risk than authenticated), the sensitivity of the target node, the length of the path (shorter paths are generally easier to traverse), and the presence of any compensating controls on intermediate nodes.

CVSS scores on vulnerabilities in nodes along the path are one input to this ranking, not the primary one. A path through a node with a CVSS 7.0 vulnerability that connects a public unauthenticated endpoint to your primary database is more urgent than a path through a CVSS 9.8 vulnerability in a library that is only reachable from an authenticated admin function that two people use. The path context changes the prioritization.

Where attack path analysis changes triage decisions

The most direct operational impact is on how an AppSec team handles new CVEs in dependencies. Without path analysis, the response to a critical CVE in a widely-used library is to check whether the library is present, see that it is, and escalate for remediation. With path analysis, the response is to check whether any attack path in the application traverses the specific vulnerable function in that library from an entry point the team cares about.

Consider a specific scenario: a critical deserialization CVE is published for a Java object serialization library. Your application uses that library in three places. Static reachability analysis shows that two of those three uses are on paths from unauthenticated endpoints, but the vulnerable deserialization function specifically is only called in one of the two. The attack path from the public API endpoint to the vulnerable function exists in Service D. Services F and G also use the library but only exercise non-vulnerable code paths in it. The remediation decision becomes: patch Service D immediately (the path is real and the function is reachable), update Services F and G on the normal patch cycle (library present, vulnerable function not reached from any path that matters).

That is the decision that attack path analysis makes possible. It is not eliminating the finding; it is providing the context to make a proportionate response decision instead of treating all three services identically because they share a library version.

Limitations to be clear about

Attack path analysis from static graph traversal is not a comprehensive security assessment. It identifies structural paths in the application; it does not assess whether those paths are actually exploitable given the specific vulnerability's requirements, the runtime configuration, or the defenses in place. A path that reaches a SQL query function is a potential SQL injection path if the data flowing to that query is attacker-controlled and unparameterized. Whether it is exploitable depends on code details that require deeper analysis.

The graph-level path analysis is the right first filter. It dramatically reduces the set of findings that need deeper investigation. But the deeper investigation is still required for the paths that survive the filter. Teams that treat path reachability as sufficient evidence of exploitability will over-escalate some findings. Teams that treat path analysis as a complete substitute for manual investigation will under-analyze others. It is a prioritization layer, not a verdict.

Getting started without a full graph solution

If you do not have automated graph construction in place today, you can approximate attack path analysis manually for your highest-risk entry points. Pick your three most sensitive target nodes (the database with customer PII, the secret store, the admin endpoint). For each target, trace backward through your architecture diagrams: which services have direct access? Which services call those services? At what depth do you hit a publicly-reachable endpoint? Do any of those paths traverse components with open critical CVEs?

This manual backward traversal will not find everything, and it will not stay accurate as your application evolves, but it will identify the most obvious high-risk paths and let you start making reachability-aware triage decisions before you have automated tooling. The insight that drives it, that risk lives in paths not in individual components, is worth internalizing regardless of what tooling you have available today.

See reachability analysis on your own code

Connect your repositories and apply a reachability filter to your existing scanner findings. No configuration changes to your current toolchain required.

Request early access