Reachability Analysis Technical Overview
Java Reachability Analysis
Java analysis performs static bytecode analysis to identify which methods in your dependencies can actually be invoked from your application's entry points. This helps determine if vulnerable code in your dependencies is truly reachable and exploitable.
How It Works
The analysis follows a straightforward pipeline:
Parse Bytecode - Read compiled .class files and extract structural information.
Build Workspace - Create an internal model of all classes, methods, and their relationships.
Select Entry Points - Identify where your application starts execution.
Construct Call Graph - Build a graph showing which methods call which other methods.
Check Reachability - Determine if vulnerable methods are reachable from entry points.
Reachability Algorithms
Java analysis supports three algorithms with different precision/performance tradeoffs:
CHA (Class Hierarchy Analysis) - Fast but imprecise, assumes any subclass could be invoked.
RTA (Rapid Type Analysis) - Balanced, only considers instantiated classes.
RTA_PLUS - Most precise, handles inheritance more intelligently.
The default is RTA_PLUS for best accuracy.
Limitations
What Java Analysis Can Do:
Analyze compiled bytecode (classes and JARs) using the
ASMlibrary.Handle Java 6+ bytecode (including lambdas, records, etc.)
Resolve lambda targets through
invokedynamicbootstrap methods.Track method calls through inheritance hierarchies.
Track instantiated types for more precise analysis (RTA/RTA_PLUS).
What Java Analysis Cannot Do:
Resolve reflection - Reflective calls (e.g.,
Class.forName,Method.invoke) are not tracked.Analyze native methods - Cannot see into JNI calls.
Handle incomplete classpath - Missing dependencies create "phantom" methods that limit analysis.
Guarantee zero false negatives - Conservative analysis may miss some call paths.
.NET Reachability Analysis
.NET assemblies contain Common Intermediate Language (CIL/IL) bytecode, the compiled form of C#, F#, and VB.NET code.
.NET analysis performs static IL (Intermediate Language) bytecode analysis to identify which methods in your dependencies can actually be invoked from your application's entry points. This helps determine if vulnerable code in your NuGet dependencies is truly reachable and exploitable.
How It Works
The analysis follows an execution pipeline:
Resolve Assemblies - Locate compiled
.dllfiles from your project.Parse IL Bytecode - Run the C# parser subprocess to extract type/method information using
dnlib.Build Workspace - Create an internal model of all classes, methods, and their relationships.
Select Entry Points - Identify where your application starts execution.
Construct Call Graph - Build a graph showing which methods call which other methods.
Check Reachability - Determine if vulnerable methods are reachable from entry points.
Reachability Algorithms
.NET analysis uses the same algorithms as Java, with different precision/performance tradeoffs:
CHA (Class Hierarchy Analysis) - Fast but imprecise, assumes any subclass could be invoked.
RTA (Rapid Type Analysis) - Balanced, only considers instantiated classes.
RTA_PLUS - Most precise, handles inheritance more intelligently.
The default is RTA_PLUS for best accuracy.
Limitations
What .NET Analysis Can Do:
Analyze compiled IL bytecode (DLLs).
Handle assemblies from any .NET version (.NET Framework, .NET Core, .NET 5+).
Track method calls through inheritance hierarchies.
Track instantiated types for precise RTA/RTA_PLUS analysis.
Handle async/await and iterator (
yield) methods (scans compiler-generated state machineMoveNextbodies).Handle lambda expressions, LINQ, and local functions (scans compiler-generated delegate/closure bodies).
What .NET Analysis Cannot Do:
Analyze reflection - Dynamic method invocations via
System.Reflectionare not tracked.Analyze
P/Invoke- Cannot see into native method calls.Handle
calliinstructions - Indirect function pointer calls cannot be resolved statically.Handle incomplete assembly references – Missing dependencies limit analysis.
Guarantee zero false negatives – Conservative analysis may miss some call paths.
JavaScript Reachability Analysis
JavaScript analysis performs static source code analysis to identify which functions in your dependencies can be invoked from your application code. This helps determine if vulnerable code in your dependencies is truly reachable.
How It Works
The analysis follows this pipeline:
Launch Agent - Start a Node.js process to parse JavaScript code.
Parse Source - Use Babel to analyze JavaScript/TypeScript files.
Build Workspace - Create a model of scopes (i.e., modules, functions, classes, objects, blocks).
Construct Call Graph - Build a graph showing which functions call which others.
Check Reachability - Determine if vulnerable functions are reachable.
NBA Algorithm
JavaScript analysis uses Name-Based Analysis (NBA), which matches function calls to functions by name. This practical approach handles JavaScript's dynamic typing, but it can produce more false positives than Java's type-based analysis.
Limitations
What JavaScript Analysis Can Do:
Analyze JavaScript and TypeScript source code.
Track function calls through modules.
Handle ES6 imports/exports.
Handle CommonJS require and module.exports.
Parse JSX and TSX syntax.
Resolve member calls written with bracket notation and a literal property name (
obj['method'](),obj[0]()).Resolve optional-chaining calls (
obj?.method(),obj?.method?.(),callback?.()).Resolve
.call(),.apply(), and.bind()to the method actually invoked (obj.method.call(ctx)is treated as a call tomethod).Resolve constructor calls (
new TargetFunction(),new lib.Widget()) to the constructed function/class.Treat a function passed by name as an argument as a potential call target (
register(targetFunction),register({ targetFunction }),receiver.method(targetFunction)), so higher-order function and callback passing is reachable.Follow a single-hop constant function-copy alias to the original member (
const f = obj.method; f()is treated as a call tomethod).Resolve a renamed destructuring alias to the source property name (
const { method: m } = obj; m()is treated as a call tomethod).Resolve a computed property whose key is a constant string variable (
const k = 'method'; obj[k]()is treated as a call tomethod).
What JavaScript Analysis Cannot Do:
Resolve calls whose method name is genuinely computed at runtime (
obj[expr](), orobj[variable]()where the variable is not a constant string).Follow multi-hop or non-constant (reassigned) function copying / aliasing across variables.
Analyze
eval()or other dynamic code execution.Handle runtime code generation.
Analyze minified code without source maps.
Guarantee which specific function is called (name-based approximation).
Guarantee zero false negatives – A call that cannot be statically resolved (for example, the remaining genuinely dynamic and multi-hop/non-constant aliasing cases above) produces no edge and is currently reported as not reachable.