- Introduced `sink-detect.js` with various security sink detection patterns categorized by type (e.g., command injection, SQL injection, file operations). - Implemented functions to build a lookup map for fast sink detection and to match sink calls against known patterns. - Added `package-lock.json` for dependency management.
120 lines
3.8 KiB
C#
120 lines
3.8 KiB
C#
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
// Copyright (c) StellaOps
|
|
|
|
using System.Collections.Immutable;
|
|
|
|
namespace StellaOps.Scanner.Explainability.Assumptions;
|
|
|
|
/// <summary>
|
|
/// A collection of assumptions associated with a finding or analysis context.
|
|
/// Provides methods for querying and validating assumptions.
|
|
/// </summary>
|
|
public sealed record AssumptionSet
|
|
{
|
|
/// <summary>
|
|
/// The unique identifier for this assumption set.
|
|
/// </summary>
|
|
public required string Id { get; init; }
|
|
|
|
/// <summary>
|
|
/// The assumptions in this set, keyed by category and key.
|
|
/// </summary>
|
|
public ImmutableArray<Assumption> Assumptions { get; init; } = [];
|
|
|
|
/// <summary>
|
|
/// When this assumption set was created.
|
|
/// </summary>
|
|
public required DateTimeOffset CreatedAt { get; init; }
|
|
|
|
/// <summary>
|
|
/// Optional context identifier (e.g., finding ID, image digest).
|
|
/// </summary>
|
|
public string? ContextId { get; init; }
|
|
|
|
/// <summary>
|
|
/// Gets all assumptions of a specific category.
|
|
/// </summary>
|
|
public IEnumerable<Assumption> GetByCategory(AssumptionCategory category) =>
|
|
Assumptions.Where(a => a.Category == category);
|
|
|
|
/// <summary>
|
|
/// Gets a specific assumption by category and key.
|
|
/// </summary>
|
|
public Assumption? Get(AssumptionCategory category, string key) =>
|
|
Assumptions.FirstOrDefault(a => a.Category == category &&
|
|
string.Equals(a.Key, key, StringComparison.OrdinalIgnoreCase));
|
|
|
|
/// <summary>
|
|
/// Returns the overall confidence level (minimum of all assumptions).
|
|
/// </summary>
|
|
public ConfidenceLevel OverallConfidence =>
|
|
Assumptions.Length == 0
|
|
? ConfidenceLevel.Low
|
|
: Assumptions.Min(a => a.Confidence);
|
|
|
|
/// <summary>
|
|
/// Returns the count of validated assumptions.
|
|
/// </summary>
|
|
public int ValidatedCount => Assumptions.Count(a => a.IsValidated);
|
|
|
|
/// <summary>
|
|
/// Returns the count of contradicted assumptions.
|
|
/// </summary>
|
|
public int ContradictedCount => Assumptions.Count(a => a.IsContradicted);
|
|
|
|
/// <summary>
|
|
/// Returns true if any assumption is contradicted by observed evidence.
|
|
/// </summary>
|
|
public bool HasContradictions => Assumptions.Any(a => a.IsContradicted);
|
|
|
|
/// <summary>
|
|
/// Returns the validation ratio (validated / total with observations).
|
|
/// </summary>
|
|
public double ValidationRatio
|
|
{
|
|
get
|
|
{
|
|
var withObservations = Assumptions.Count(a => a.ObservedValue is not null);
|
|
return withObservations == 0 ? 0.0 : (double)ValidatedCount / withObservations;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a new AssumptionSet with an additional assumption.
|
|
/// </summary>
|
|
public AssumptionSet WithAssumption(Assumption assumption) =>
|
|
this with { Assumptions = Assumptions.Add(assumption) };
|
|
|
|
/// <summary>
|
|
/// Creates a new AssumptionSet with updated observation for an assumption.
|
|
/// </summary>
|
|
public AssumptionSet WithObservation(AssumptionCategory category, string key, string observedValue)
|
|
{
|
|
var index = Assumptions.FindIndex(a =>
|
|
a.Category == category &&
|
|
string.Equals(a.Key, key, StringComparison.OrdinalIgnoreCase));
|
|
|
|
if (index < 0)
|
|
return this;
|
|
|
|
var updated = Assumptions[index] with { ObservedValue = observedValue };
|
|
return this with { Assumptions = Assumptions.SetItem(index, updated) };
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extension methods for ImmutableArray to support FindIndex.
|
|
/// </summary>
|
|
internal static class ImmutableArrayExtensions
|
|
{
|
|
public static int FindIndex<T>(this ImmutableArray<T> array, Func<T, bool> predicate)
|
|
{
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (predicate(array[i]))
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
}
|