feat: Implement IsolatedReplayContext for deterministic audit replay
- Added IsolatedReplayContext class to provide an isolated environment for replaying audit bundles without external calls. - Introduced methods for initializing the context, verifying input digests, and extracting inputs for policy evaluation. - Created supporting interfaces and options for context configuration. feat: Create ReplayExecutor for executing policy re-evaluation and verdict comparison - Developed ReplayExecutor class to handle the execution of replay processes, including input verification and verdict comparison. - Implemented detailed drift detection and error handling during replay execution. - Added interfaces for policy evaluation and replay execution options. feat: Add ScanSnapshotFetcher for fetching scan data and snapshots - Introduced ScanSnapshotFetcher class to retrieve necessary scan data and snapshots for audit bundle creation. - Implemented methods to fetch scan metadata, advisory feeds, policy snapshots, and VEX statements. - Created supporting interfaces for scan data, feed snapshots, and policy snapshots.
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
// Copyright (c) StellaOps
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using StellaOps.Scanner.Reachability.Stack;
|
||||
|
||||
namespace StellaOps.Scanner.Reachability.Layer1;
|
||||
|
||||
/// <summary>
|
||||
/// Layer 1 analyzer: Static call graph reachability.
|
||||
/// Determines if vulnerable symbols are reachable from application entrypoints
|
||||
/// via static code analysis.
|
||||
/// </summary>
|
||||
public interface ILayer1Analyzer
|
||||
{
|
||||
/// <summary>
|
||||
/// Analyzes static reachability of a vulnerable symbol.
|
||||
/// </summary>
|
||||
/// <param name="symbol">The vulnerable symbol to check</param>
|
||||
/// <param name="graph">The call graph to analyze</param>
|
||||
/// <param name="entrypoints">Known application entrypoints</param>
|
||||
/// <param name="ct">Cancellation token</param>
|
||||
/// <returns>Layer 1 reachability analysis result</returns>
|
||||
Task<ReachabilityLayer1> AnalyzeAsync(
|
||||
VulnerableSymbol symbol,
|
||||
CallGraph graph,
|
||||
ImmutableArray<Entrypoint> entrypoints,
|
||||
CancellationToken ct = default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A call graph representing method/function calls in the application.
|
||||
/// </summary>
|
||||
public sealed record CallGraph
|
||||
{
|
||||
/// <summary>Unique identifier for this call graph</summary>
|
||||
public required string Id { get; init; }
|
||||
|
||||
/// <summary>When this call graph was generated</summary>
|
||||
public required DateTimeOffset GeneratedAt { get; init; }
|
||||
|
||||
/// <summary>All nodes in the graph</summary>
|
||||
public ImmutableArray<CallGraphNode> Nodes { get; init; } = [];
|
||||
|
||||
/// <summary>All edges (calls) in the graph</summary>
|
||||
public ImmutableArray<CallGraphEdge> Edges { get; init; } = [];
|
||||
|
||||
/// <summary>Source of this call graph</summary>
|
||||
public required CallGraphSource Source { get; init; }
|
||||
|
||||
/// <summary>Language/platform this graph represents</summary>
|
||||
public required string Language { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A node in the call graph (method/function).
|
||||
/// </summary>
|
||||
public sealed record CallGraphNode(
|
||||
string Id,
|
||||
string Name,
|
||||
string? ClassName,
|
||||
string? Namespace,
|
||||
string? FileName,
|
||||
int? LineNumber,
|
||||
bool IsEntrypoint,
|
||||
bool IsExternal
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// An edge in the call graph (call from one method to another).
|
||||
/// </summary>
|
||||
public sealed record CallGraphEdge(
|
||||
string FromNodeId,
|
||||
string ToNodeId,
|
||||
CallSiteType CallType,
|
||||
int? LineNumber,
|
||||
bool IsConditional
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Source of a call graph.
|
||||
/// </summary>
|
||||
public enum CallGraphSource
|
||||
{
|
||||
/// <summary>Roslyn/ILSpy analysis for .NET</summary>
|
||||
DotNetAnalysis,
|
||||
|
||||
/// <summary>TypeScript/JavaScript AST analysis</summary>
|
||||
NodeAnalysis,
|
||||
|
||||
/// <summary>javap/ASM analysis for Java</summary>
|
||||
JavaAnalysis,
|
||||
|
||||
/// <summary>go/analysis for Go</summary>
|
||||
GoAnalysis,
|
||||
|
||||
/// <summary>Python AST analysis</summary>
|
||||
PythonAnalysis,
|
||||
|
||||
/// <summary>Binary disassembly</summary>
|
||||
BinaryAnalysis,
|
||||
|
||||
/// <summary>Combined from multiple sources</summary>
|
||||
Composite
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Input for Layer 1 analysis.
|
||||
/// </summary>
|
||||
public sealed record Layer1AnalysisInput
|
||||
{
|
||||
public required VulnerableSymbol Symbol { get; init; }
|
||||
public required CallGraph Graph { get; init; }
|
||||
public ImmutableArray<Entrypoint> Entrypoints { get; init; } = [];
|
||||
public Layer1AnalysisOptions? Options { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Options for Layer 1 analysis.
|
||||
/// </summary>
|
||||
public sealed record Layer1AnalysisOptions
|
||||
{
|
||||
/// <summary>Maximum call path depth to explore</summary>
|
||||
public int MaxPathDepth { get; init; } = 100;
|
||||
|
||||
/// <summary>Maximum number of paths to return</summary>
|
||||
public int MaxPaths { get; init; } = 10;
|
||||
|
||||
/// <summary>Include paths through external libraries</summary>
|
||||
public bool IncludeExternalPaths { get; init; } = true;
|
||||
|
||||
/// <summary>Consider reflection calls as potential paths</summary>
|
||||
public bool ConsiderReflection { get; init; } = true;
|
||||
|
||||
/// <summary>Consider dynamic dispatch as potential paths</summary>
|
||||
public bool ConsiderDynamicDispatch { get; init; } = true;
|
||||
}
|
||||
Reference in New Issue
Block a user