Complete batch 012 (golden set diff) and 013 (advisory chat), fix build errors
Sprints completed: - SPRINT_20260110_012_* (golden set diff layer - 10 sprints) - SPRINT_20260110_013_* (advisory chat - 4 sprints) Build fixes applied: - Fix namespace conflicts with Microsoft.Extensions.Options.Options.Create - Fix VexDecisionReachabilityIntegrationTests API drift (major rewrite) - Fix VexSchemaValidationTests FluentAssertions method name - Fix FixChainGateIntegrationTests ambiguous type references - Fix AdvisoryAI test files required properties and namespace aliases - Add stub types for CveMappingController (ICveSymbolMappingService) - Fix VerdictBuilderService static context issue Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
// Sprint: SPRINT_20260109_009_003_BE_cve_symbol_mapping
|
||||
// Task: Implement API endpoints
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.RateLimiting;
|
||||
using StellaOps.Reachability.Core.CveMapping;
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
// Licensed to StellaOps under the AGPL-3.0-or-later license.
|
||||
// Stub types for CVE-Symbol mapping service
|
||||
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace StellaOps.Reachability.Core.CveMapping;
|
||||
|
||||
/// <summary>
|
||||
/// Service for CVE-symbol mapping operations.
|
||||
/// </summary>
|
||||
public interface ICveSymbolMappingService
|
||||
{
|
||||
Task<IReadOnlyList<CveSymbolMapping>> GetMappingsForCveAsync(string cveId, CancellationToken cancellationToken);
|
||||
Task<IReadOnlyList<CveSymbolMapping>> GetMappingsForPackageAsync(string purl, CancellationToken cancellationToken);
|
||||
Task<IReadOnlyList<CveSymbolMapping>> SearchBySymbolAsync(string symbol, string? language, CancellationToken cancellationToken);
|
||||
Task<CveSymbolMapping> AddOrUpdateMappingAsync(CveSymbolMapping mapping, CancellationToken cancellationToken);
|
||||
Task<PatchAnalysisResult> AnalyzePatchAsync(string? commitUrl, string? diffContent, CancellationToken cancellationToken);
|
||||
Task<IReadOnlyList<CveSymbolMapping>> EnrichFromOsvAsync(string cveId, CancellationToken cancellationToken);
|
||||
Task<MappingStats> GetStatsAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A mapping between a CVE and a vulnerable symbol.
|
||||
/// </summary>
|
||||
public record CveSymbolMapping
|
||||
{
|
||||
public required string CveId { get; init; }
|
||||
public required string Purl { get; init; }
|
||||
public required VulnerableSymbol Symbol { get; init; }
|
||||
public MappingSource Source { get; init; }
|
||||
public double Confidence { get; init; }
|
||||
public VulnerabilityType VulnerabilityType { get; init; }
|
||||
public ImmutableArray<string> AffectedVersions { get; init; } = [];
|
||||
public ImmutableArray<string> FixedVersions { get; init; } = [];
|
||||
public string? EvidenceUri { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a vulnerable symbol (function/method).
|
||||
/// </summary>
|
||||
public record VulnerableSymbol
|
||||
{
|
||||
public required string Symbol { get; init; }
|
||||
public string? CanonicalId { get; init; }
|
||||
public string? FilePath { get; init; }
|
||||
public int? StartLine { get; init; }
|
||||
public int? EndLine { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Source of the mapping.
|
||||
/// </summary>
|
||||
public enum MappingSource
|
||||
{
|
||||
Unknown = 0,
|
||||
Osv = 1,
|
||||
Nvd = 2,
|
||||
Manual = 3,
|
||||
PatchAnalysis = 4,
|
||||
Vendor = 5
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type of vulnerability.
|
||||
/// </summary>
|
||||
public enum VulnerabilityType
|
||||
{
|
||||
Unknown = 0,
|
||||
BufferOverflow = 1,
|
||||
SqlInjection = 2,
|
||||
XSS = 3,
|
||||
CommandInjection = 4,
|
||||
PathTraversal = 5,
|
||||
Deserialization = 6,
|
||||
Cryptographic = 7,
|
||||
Other = 99
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Result of patch analysis.
|
||||
/// </summary>
|
||||
public record PatchAnalysisResult
|
||||
{
|
||||
public required IReadOnlyList<ExtractedSymbol> ExtractedSymbols { get; init; }
|
||||
public DateTimeOffset AnalyzedAt { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Symbol extracted from a patch.
|
||||
/// </summary>
|
||||
public record ExtractedSymbol
|
||||
{
|
||||
public required string Symbol { get; init; }
|
||||
public string? FilePath { get; init; }
|
||||
public int? StartLine { get; init; }
|
||||
public int? EndLine { get; init; }
|
||||
public ChangeType ChangeType { get; init; }
|
||||
public string? Language { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Type of change in a patch.
|
||||
/// </summary>
|
||||
public enum ChangeType
|
||||
{
|
||||
Unknown = 0,
|
||||
Added = 1,
|
||||
Modified = 2,
|
||||
Deleted = 3
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Statistics about the mapping corpus.
|
||||
/// </summary>
|
||||
public record MappingStats
|
||||
{
|
||||
public int TotalMappings { get; init; }
|
||||
public int UniqueCves { get; init; }
|
||||
public int UniquePackages { get; init; }
|
||||
public Dictionary<string, int>? BySource { get; init; }
|
||||
public Dictionary<string, int>? ByVulnerabilityType { get; init; }
|
||||
public double AverageConfidence { get; init; }
|
||||
public DateTimeOffset LastUpdated { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Null implementation of the CVE symbol mapping service.
|
||||
/// </summary>
|
||||
public sealed class NullCveSymbolMappingService : ICveSymbolMappingService
|
||||
{
|
||||
public Task<IReadOnlyList<CveSymbolMapping>> GetMappingsForCveAsync(string cveId, CancellationToken cancellationToken)
|
||||
=> Task.FromResult<IReadOnlyList<CveSymbolMapping>>([]);
|
||||
|
||||
public Task<IReadOnlyList<CveSymbolMapping>> GetMappingsForPackageAsync(string purl, CancellationToken cancellationToken)
|
||||
=> Task.FromResult<IReadOnlyList<CveSymbolMapping>>([]);
|
||||
|
||||
public Task<IReadOnlyList<CveSymbolMapping>> SearchBySymbolAsync(string symbol, string? language, CancellationToken cancellationToken)
|
||||
=> Task.FromResult<IReadOnlyList<CveSymbolMapping>>([]);
|
||||
|
||||
public Task<CveSymbolMapping> AddOrUpdateMappingAsync(CveSymbolMapping mapping, CancellationToken cancellationToken)
|
||||
=> Task.FromResult(mapping);
|
||||
|
||||
public Task<PatchAnalysisResult> AnalyzePatchAsync(string? commitUrl, string? diffContent, CancellationToken cancellationToken)
|
||||
=> Task.FromResult(new PatchAnalysisResult { ExtractedSymbols = [], AnalyzedAt = DateTimeOffset.UtcNow });
|
||||
|
||||
public Task<IReadOnlyList<CveSymbolMapping>> EnrichFromOsvAsync(string cveId, CancellationToken cancellationToken)
|
||||
=> Task.FromResult<IReadOnlyList<CveSymbolMapping>>([]);
|
||||
|
||||
public Task<MappingStats> GetStatsAsync(CancellationToken cancellationToken)
|
||||
=> Task.FromResult(new MappingStats { LastUpdated = DateTimeOffset.UtcNow });
|
||||
}
|
||||
Reference in New Issue
Block a user