// -----------------------------------------------------------------------------
// 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;
///
/// A vulnerability surface represents the specific methods that changed
/// between a vulnerable and fixed version of a package.
///
public sealed record VulnSurface
{
///
/// Database ID.
///
[JsonPropertyName("surface_id")]
public long SurfaceId { get; init; }
///
/// CVE ID (e.g., "CVE-2024-12345").
///
[JsonPropertyName("cve_id")]
public required string CveId { get; init; }
///
/// Package identifier (PURL format preferred).
///
[JsonPropertyName("package_id")]
public required string PackageId { get; init; }
///
/// Ecosystem (nuget, npm, maven, pypi).
///
[JsonPropertyName("ecosystem")]
public required string Ecosystem { get; init; }
///
/// Vulnerable version analyzed.
///
[JsonPropertyName("vuln_version")]
public required string VulnVersion { get; init; }
///
/// Fixed version used for diff.
///
[JsonPropertyName("fixed_version")]
public required string FixedVersion { get; init; }
///
/// Sink methods (vulnerable code locations).
///
[JsonPropertyName("sinks")]
public IReadOnlyList Sinks { get; init; } = [];
///
/// Number of trigger methods that can reach sinks.
///
[JsonPropertyName("trigger_count")]
public int TriggerCount { get; init; }
///
/// Surface computation status.
///
[JsonPropertyName("status")]
public VulnSurfaceStatus Status { get; init; }
///
/// Confidence score (0.0-1.0).
///
[JsonPropertyName("confidence")]
public double Confidence { get; init; } = 1.0;
///
/// When the surface was computed.
///
[JsonPropertyName("computed_at")]
public DateTimeOffset ComputedAt { get; init; }
///
/// Error message if computation failed.
///
[JsonPropertyName("error")]
public string? Error { get; init; }
}
///
/// A sink method - a specific method that was modified in the security fix.
///
public sealed record VulnSurfaceSink
{
///
/// Database ID.
///
[JsonPropertyName("sink_id")]
public long SinkId { get; init; }
///
/// Parent surface ID.
///
[JsonPropertyName("surface_id")]
public long SurfaceId { get; init; }
///
/// Normalized method key.
///
[JsonPropertyName("method_key")]
public required string MethodKey { get; init; }
///
/// Declaring type/class name.
///
[JsonPropertyName("declaring_type")]
public required string DeclaringType { get; init; }
///
/// Method name.
///
[JsonPropertyName("method_name")]
public required string MethodName { get; init; }
///
/// Namespace/package.
///
[JsonPropertyName("namespace")]
public string? Namespace { get; init; }
///
/// Method signature.
///
[JsonPropertyName("signature")]
public string? Signature { get; init; }
///
/// Type of change detected.
///
[JsonPropertyName("change_type")]
public MethodChangeType ChangeType { get; init; }
///
/// Hash of the method in vulnerable version.
///
[JsonPropertyName("vuln_hash")]
public string? VulnHash { get; init; }
///
/// Hash of the method in fixed version.
///
[JsonPropertyName("fixed_hash")]
public string? FixedHash { get; init; }
///
/// Whether this sink is directly exploitable.
///
[JsonPropertyName("is_direct_exploit")]
public bool IsDirectExploit { get; init; }
///
/// Whether the method is public.
///
[JsonPropertyName("is_public")]
public bool IsPublic { get; init; }
///
/// Number of parameters.
///
[JsonPropertyName("parameter_count")]
public int? ParameterCount { get; init; }
///
/// Return type.
///
[JsonPropertyName("return_type")]
public string? ReturnType { get; init; }
///
/// Source file path (if available from debug symbols).
///
[JsonPropertyName("source_file")]
public string? SourceFile { get; init; }
///
/// Start line number.
///
[JsonPropertyName("start_line")]
public int? StartLine { get; init; }
///
/// End line number.
///
[JsonPropertyName("end_line")]
public int? EndLine { get; init; }
}
///
/// Status of vulnerability surface computation.
///
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum VulnSurfaceStatus
{
///
/// Computation pending.
///
Pending,
///
/// Computation in progress.
///
Computing,
///
/// Successfully computed.
///
Computed,
///
/// Computation failed.
///
Failed,
///
/// No diff detected (versions identical).
///
NoDiff,
///
/// Package not found.
///
PackageNotFound
}
///
/// Type of method change detected.
///
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum MethodChangeType
{
///
/// Method body was modified.
///
Modified,
///
/// Method was added in fixed version.
///
Added,
///
/// Method was removed in fixed version.
///
Removed,
///
/// Method signature changed.
///
SignatureChanged
}