- Implemented PathViewerComponent for visualizing reachability call paths. - Added RiskDriftCardComponent to display reachability drift results. - Created corresponding HTML templates and SCSS styles for both components. - Introduced test fixtures for reachability analysis in JSON format. - Enhanced user interaction with collapsible and expandable features in PathViewer. - Included risk trend visualization and summary metrics in RiskDriftCard.
263 lines
6.4 KiB
C#
263 lines
6.4 KiB
C#
// -----------------------------------------------------------------------------
|
|
// VulnSurface.cs
|
|
// Sprint: SPRINT_3700_0002_0001_vuln_surfaces_core
|
|
// Description: Core models for vulnerability surface computation.
|
|
// -----------------------------------------------------------------------------
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace StellaOps.Scanner.VulnSurfaces.Models;
|
|
|
|
/// <summary>
|
|
/// A vulnerability surface represents the specific methods that changed
|
|
/// between a vulnerable and fixed version of a package.
|
|
/// </summary>
|
|
public sealed record VulnSurface
|
|
{
|
|
/// <summary>
|
|
/// Database ID.
|
|
/// </summary>
|
|
[JsonPropertyName("surface_id")]
|
|
public long SurfaceId { get; init; }
|
|
|
|
/// <summary>
|
|
/// CVE ID (e.g., "CVE-2024-12345").
|
|
/// </summary>
|
|
[JsonPropertyName("cve_id")]
|
|
public required string CveId { get; init; }
|
|
|
|
/// <summary>
|
|
/// Package identifier (PURL format preferred).
|
|
/// </summary>
|
|
[JsonPropertyName("package_id")]
|
|
public required string PackageId { get; init; }
|
|
|
|
/// <summary>
|
|
/// Ecosystem (nuget, npm, maven, pypi).
|
|
/// </summary>
|
|
[JsonPropertyName("ecosystem")]
|
|
public required string Ecosystem { get; init; }
|
|
|
|
/// <summary>
|
|
/// Vulnerable version analyzed.
|
|
/// </summary>
|
|
[JsonPropertyName("vuln_version")]
|
|
public required string VulnVersion { get; init; }
|
|
|
|
/// <summary>
|
|
/// Fixed version used for diff.
|
|
/// </summary>
|
|
[JsonPropertyName("fixed_version")]
|
|
public required string FixedVersion { get; init; }
|
|
|
|
/// <summary>
|
|
/// Sink methods (vulnerable code locations).
|
|
/// </summary>
|
|
[JsonPropertyName("sinks")]
|
|
public IReadOnlyList<VulnSurfaceSink> Sinks { get; init; } = [];
|
|
|
|
/// <summary>
|
|
/// Number of trigger methods that can reach sinks.
|
|
/// </summary>
|
|
[JsonPropertyName("trigger_count")]
|
|
public int TriggerCount { get; init; }
|
|
|
|
/// <summary>
|
|
/// Surface computation status.
|
|
/// </summary>
|
|
[JsonPropertyName("status")]
|
|
public VulnSurfaceStatus Status { get; init; }
|
|
|
|
/// <summary>
|
|
/// Confidence score (0.0-1.0).
|
|
/// </summary>
|
|
[JsonPropertyName("confidence")]
|
|
public double Confidence { get; init; } = 1.0;
|
|
|
|
/// <summary>
|
|
/// When the surface was computed.
|
|
/// </summary>
|
|
[JsonPropertyName("computed_at")]
|
|
public DateTimeOffset ComputedAt { get; init; }
|
|
|
|
/// <summary>
|
|
/// Error message if computation failed.
|
|
/// </summary>
|
|
[JsonPropertyName("error")]
|
|
public string? Error { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// A sink method - a specific method that was modified in the security fix.
|
|
/// </summary>
|
|
public sealed record VulnSurfaceSink
|
|
{
|
|
/// <summary>
|
|
/// Database ID.
|
|
/// </summary>
|
|
[JsonPropertyName("sink_id")]
|
|
public long SinkId { get; init; }
|
|
|
|
/// <summary>
|
|
/// Parent surface ID.
|
|
/// </summary>
|
|
[JsonPropertyName("surface_id")]
|
|
public long SurfaceId { get; init; }
|
|
|
|
/// <summary>
|
|
/// Normalized method key.
|
|
/// </summary>
|
|
[JsonPropertyName("method_key")]
|
|
public required string MethodKey { get; init; }
|
|
|
|
/// <summary>
|
|
/// Declaring type/class name.
|
|
/// </summary>
|
|
[JsonPropertyName("declaring_type")]
|
|
public required string DeclaringType { get; init; }
|
|
|
|
/// <summary>
|
|
/// Method name.
|
|
/// </summary>
|
|
[JsonPropertyName("method_name")]
|
|
public required string MethodName { get; init; }
|
|
|
|
/// <summary>
|
|
/// Namespace/package.
|
|
/// </summary>
|
|
[JsonPropertyName("namespace")]
|
|
public string? Namespace { get; init; }
|
|
|
|
/// <summary>
|
|
/// Method signature.
|
|
/// </summary>
|
|
[JsonPropertyName("signature")]
|
|
public string? Signature { get; init; }
|
|
|
|
/// <summary>
|
|
/// Type of change detected.
|
|
/// </summary>
|
|
[JsonPropertyName("change_type")]
|
|
public MethodChangeType ChangeType { get; init; }
|
|
|
|
/// <summary>
|
|
/// Hash of the method in vulnerable version.
|
|
/// </summary>
|
|
[JsonPropertyName("vuln_hash")]
|
|
public string? VulnHash { get; init; }
|
|
|
|
/// <summary>
|
|
/// Hash of the method in fixed version.
|
|
/// </summary>
|
|
[JsonPropertyName("fixed_hash")]
|
|
public string? FixedHash { get; init; }
|
|
|
|
/// <summary>
|
|
/// Whether this sink is directly exploitable.
|
|
/// </summary>
|
|
[JsonPropertyName("is_direct_exploit")]
|
|
public bool IsDirectExploit { get; init; }
|
|
|
|
/// <summary>
|
|
/// Whether the method is public.
|
|
/// </summary>
|
|
[JsonPropertyName("is_public")]
|
|
public bool IsPublic { get; init; }
|
|
|
|
/// <summary>
|
|
/// Number of parameters.
|
|
/// </summary>
|
|
[JsonPropertyName("parameter_count")]
|
|
public int? ParameterCount { get; init; }
|
|
|
|
/// <summary>
|
|
/// Return type.
|
|
/// </summary>
|
|
[JsonPropertyName("return_type")]
|
|
public string? ReturnType { get; init; }
|
|
|
|
/// <summary>
|
|
/// Source file path (if available from debug symbols).
|
|
/// </summary>
|
|
[JsonPropertyName("source_file")]
|
|
public string? SourceFile { get; init; }
|
|
|
|
/// <summary>
|
|
/// Start line number.
|
|
/// </summary>
|
|
[JsonPropertyName("start_line")]
|
|
public int? StartLine { get; init; }
|
|
|
|
/// <summary>
|
|
/// End line number.
|
|
/// </summary>
|
|
[JsonPropertyName("end_line")]
|
|
public int? EndLine { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Status of vulnerability surface computation.
|
|
/// </summary>
|
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
|
public enum VulnSurfaceStatus
|
|
{
|
|
/// <summary>
|
|
/// Computation pending.
|
|
/// </summary>
|
|
Pending,
|
|
|
|
/// <summary>
|
|
/// Computation in progress.
|
|
/// </summary>
|
|
Computing,
|
|
|
|
/// <summary>
|
|
/// Successfully computed.
|
|
/// </summary>
|
|
Computed,
|
|
|
|
/// <summary>
|
|
/// Computation failed.
|
|
/// </summary>
|
|
Failed,
|
|
|
|
/// <summary>
|
|
/// No diff detected (versions identical).
|
|
/// </summary>
|
|
NoDiff,
|
|
|
|
/// <summary>
|
|
/// Package not found.
|
|
/// </summary>
|
|
PackageNotFound
|
|
}
|
|
|
|
/// <summary>
|
|
/// Type of method change detected.
|
|
/// </summary>
|
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
|
public enum MethodChangeType
|
|
{
|
|
/// <summary>
|
|
/// Method body was modified.
|
|
/// </summary>
|
|
Modified,
|
|
|
|
/// <summary>
|
|
/// Method was added in fixed version.
|
|
/// </summary>
|
|
Added,
|
|
|
|
/// <summary>
|
|
/// Method was removed in fixed version.
|
|
/// </summary>
|
|
Removed,
|
|
|
|
/// <summary>
|
|
/// Method signature changed.
|
|
/// </summary>
|
|
SignatureChanged
|
|
}
|