feat: add security sink detection patterns for JavaScript/TypeScript
- 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.
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
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";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user