// SPDX-License-Identifier: BUSL-1.1
// Copyright (c) StellaOps
using System.Collections.Immutable;
using StellaOps.Scanner.Reachability.Stack;
namespace StellaOps.Scanner.Reachability.Layer1;
///
/// Layer 1 analyzer: Static call graph reachability.
/// Determines if vulnerable symbols are reachable from application entrypoints
/// via static code analysis.
///
public interface ILayer1Analyzer
{
///
/// Analyzes static reachability of a vulnerable symbol.
///
/// The vulnerable symbol to check
/// The call graph to analyze
/// Known application entrypoints
/// Cancellation token
/// Layer 1 reachability analysis result
Task AnalyzeAsync(
VulnerableSymbol symbol,
CallGraph graph,
ImmutableArray entrypoints,
CancellationToken ct = default);
}
///
/// A call graph representing method/function calls in the application.
///
public sealed record CallGraph
{
/// Unique identifier for this call graph
public required string Id { get; init; }
/// When this call graph was generated
public required DateTimeOffset GeneratedAt { get; init; }
/// All nodes in the graph
public ImmutableArray Nodes { get; init; } = [];
/// All edges (calls) in the graph
public ImmutableArray Edges { get; init; } = [];
/// Source of this call graph
public required CallGraphSource Source { get; init; }
/// Language/platform this graph represents
public required string Language { get; init; }
}
///
/// A node in the call graph (method/function).
///
public sealed record CallGraphNode(
string Id,
string Name,
string? ClassName,
string? Namespace,
string? FileName,
int? LineNumber,
bool IsEntrypoint,
bool IsExternal
);
///
/// An edge in the call graph (call from one method to another).
///
public sealed record CallGraphEdge(
string FromNodeId,
string ToNodeId,
CallSiteType CallType,
int? LineNumber,
bool IsConditional
);
///
/// Source of a call graph.
///
public enum CallGraphSource
{
/// Roslyn/ILSpy analysis for .NET
DotNetAnalysis,
/// TypeScript/JavaScript AST analysis
NodeAnalysis,
/// javap/ASM analysis for Java
JavaAnalysis,
/// go/analysis for Go
GoAnalysis,
/// Python AST analysis
PythonAnalysis,
/// Binary disassembly
BinaryAnalysis,
/// Combined from multiple sources
Composite
}
///
/// Input for Layer 1 analysis.
///
public sealed record Layer1AnalysisInput
{
public required VulnerableSymbol Symbol { get; init; }
public required CallGraph Graph { get; init; }
public ImmutableArray Entrypoints { get; init; } = [];
public Layer1AnalysisOptions? Options { get; init; }
}
///
/// Options for Layer 1 analysis.
///
public sealed record Layer1AnalysisOptions
{
/// Maximum call path depth to explore
public int MaxPathDepth { get; init; } = 100;
/// Maximum number of paths to return
public int MaxPaths { get; init; } = 10;
/// Include paths through external libraries
public bool IncludeExternalPaths { get; init; } = true;
/// Consider reflection calls as potential paths
public bool ConsiderReflection { get; init; } = true;
/// Consider dynamic dispatch as potential paths
public bool ConsiderDynamicDispatch { get; init; } = true;
}