- 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.
189 lines
5.8 KiB
C#
189 lines
5.8 KiB
C#
namespace StellaOps.Policy.Engine.Attestation;
|
|
|
|
/// <summary>
|
|
/// Structured reason codes explaining verdict outcomes.
|
|
/// Format: CATEGORY.SUBCATEGORY.DETAIL
|
|
/// </summary>
|
|
public enum VerdictReasonCode
|
|
{
|
|
// PASS reasons
|
|
/// <summary>
|
|
/// No CVEs found in artifact.
|
|
/// </summary>
|
|
PassNoCves,
|
|
|
|
/// <summary>
|
|
/// All CVEs are not reachable.
|
|
/// </summary>
|
|
PassNotReachable,
|
|
|
|
/// <summary>
|
|
/// All CVEs are covered by VEX not_affected statements.
|
|
/// </summary>
|
|
PassVexNotAffected,
|
|
|
|
/// <summary>
|
|
/// All CVEs are below severity threshold.
|
|
/// </summary>
|
|
PassBelowThreshold,
|
|
|
|
// FAIL reasons - CVE
|
|
/// <summary>
|
|
/// Reachable CVE exceeds severity threshold.
|
|
/// </summary>
|
|
FailCveReachable,
|
|
|
|
/// <summary>
|
|
/// CVE in CISA KEV (Known Exploited Vulnerabilities).
|
|
/// </summary>
|
|
FailCveKev,
|
|
|
|
/// <summary>
|
|
/// CVE with high EPSS score.
|
|
/// </summary>
|
|
FailCveEpss,
|
|
|
|
/// <summary>
|
|
/// CVE severity exceeds maximum allowed.
|
|
/// </summary>
|
|
FailCveSeverity,
|
|
|
|
// FAIL reasons - Policy
|
|
/// <summary>
|
|
/// License violation detected.
|
|
/// </summary>
|
|
FailPolicyLicense,
|
|
|
|
/// <summary>
|
|
/// Blocked package detected.
|
|
/// </summary>
|
|
FailPolicyBlockedPackage,
|
|
|
|
/// <summary>
|
|
/// Unknown budget exceeded.
|
|
/// </summary>
|
|
FailPolicyUnknownBudget,
|
|
|
|
/// <summary>
|
|
/// SBOM completeness below threshold.
|
|
/// </summary>
|
|
FailPolicySbomCompleteness,
|
|
|
|
// FAIL reasons - Provenance
|
|
/// <summary>
|
|
/// Missing provenance attestation.
|
|
/// </summary>
|
|
FailProvenanceMissing,
|
|
|
|
/// <summary>
|
|
/// Provenance signature invalid.
|
|
/// </summary>
|
|
FailProvenanceInvalid,
|
|
|
|
// EXCEPTION reasons
|
|
/// <summary>
|
|
/// CVE covered by approved exception.
|
|
/// </summary>
|
|
ExceptionCve,
|
|
|
|
/// <summary>
|
|
/// License covered by approved exception.
|
|
/// </summary>
|
|
ExceptionLicense,
|
|
|
|
/// <summary>
|
|
/// Unknowns covered by approved exception.
|
|
/// </summary>
|
|
ExceptionUnknown,
|
|
|
|
// INDETERMINATE reasons
|
|
/// <summary>
|
|
/// Insufficient data to evaluate.
|
|
/// </summary>
|
|
IndeterminateInsufficientData,
|
|
|
|
/// <summary>
|
|
/// Analyzer does not support this artifact type.
|
|
/// </summary>
|
|
IndeterminateUnsupported,
|
|
|
|
/// <summary>
|
|
/// Conflicting VEX statements.
|
|
/// </summary>
|
|
IndeterminateVexConflict,
|
|
|
|
/// <summary>
|
|
/// Required knowledge source unavailable.
|
|
/// </summary>
|
|
IndeterminateFeedUnavailable
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extension methods for reason code handling.
|
|
/// </summary>
|
|
public static class VerdictReasonCodeExtensions
|
|
{
|
|
/// <summary>
|
|
/// Gets the category of a reason code (Pass, Fail, Exception, Indeterminate).
|
|
/// </summary>
|
|
public static string GetCategory(this VerdictReasonCode code)
|
|
{
|
|
return code.ToString() switch
|
|
{
|
|
var s when s.StartsWith("Pass", StringComparison.Ordinal) => "Pass",
|
|
var s when s.StartsWith("Fail", StringComparison.Ordinal) => "Fail",
|
|
var s when s.StartsWith("Exception", StringComparison.Ordinal) => "Exception",
|
|
var s when s.StartsWith("Indeterminate", StringComparison.Ordinal) => "Indeterminate",
|
|
_ => "Unknown"
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a human-readable description of the reason code.
|
|
/// </summary>
|
|
public static string GetDescription(this VerdictReasonCode code)
|
|
{
|
|
return code switch
|
|
{
|
|
VerdictReasonCode.PassNoCves => "No CVEs found in artifact",
|
|
VerdictReasonCode.PassNotReachable => "All CVEs are not reachable",
|
|
VerdictReasonCode.PassVexNotAffected => "All CVEs covered by VEX not_affected statements",
|
|
VerdictReasonCode.PassBelowThreshold => "All CVEs below severity threshold",
|
|
VerdictReasonCode.FailCveReachable => "Reachable CVE exceeds severity threshold",
|
|
VerdictReasonCode.FailCveKev => "CVE in CISA Known Exploited Vulnerabilities list",
|
|
VerdictReasonCode.FailCveEpss => "CVE with high EPSS score",
|
|
VerdictReasonCode.FailCveSeverity => "CVE severity exceeds maximum allowed",
|
|
VerdictReasonCode.FailPolicyLicense => "License violation detected",
|
|
VerdictReasonCode.FailPolicyBlockedPackage => "Blocked package detected",
|
|
VerdictReasonCode.FailPolicyUnknownBudget => "Unknown budget exceeded",
|
|
VerdictReasonCode.FailPolicySbomCompleteness => "SBOM completeness below threshold",
|
|
VerdictReasonCode.FailProvenanceMissing => "Missing provenance attestation",
|
|
VerdictReasonCode.FailProvenanceInvalid => "Provenance signature invalid",
|
|
VerdictReasonCode.ExceptionCve => "CVE covered by approved exception",
|
|
VerdictReasonCode.ExceptionLicense => "License covered by approved exception",
|
|
VerdictReasonCode.ExceptionUnknown => "Unknowns covered by approved exception",
|
|
VerdictReasonCode.IndeterminateInsufficientData => "Insufficient data to evaluate",
|
|
VerdictReasonCode.IndeterminateUnsupported => "Analyzer does not support this artifact type",
|
|
VerdictReasonCode.IndeterminateVexConflict => "Conflicting VEX statements",
|
|
VerdictReasonCode.IndeterminateFeedUnavailable => "Required knowledge source unavailable",
|
|
_ => code.ToString()
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if a reason code indicates a passing state.
|
|
/// </summary>
|
|
public static bool IsPass(this VerdictReasonCode code)
|
|
{
|
|
return code.GetCategory() == "Pass";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if a reason code indicates a failing state.
|
|
/// </summary>
|
|
public static bool IsFail(this VerdictReasonCode code)
|
|
{
|
|
return code.GetCategory() == "Fail";
|
|
}
|
|
}
|