// 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; }