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:
StellaOps Bot
2025-12-22 23:21:21 +02:00
parent 3ba7157b00
commit 5146204f1b
529 changed files with 73579 additions and 5985 deletions

View File

@@ -0,0 +1,211 @@
// -----------------------------------------------------------------------------
// BudgetExceededEventFactory.cs
// Sprint: SPRINT_4300_0002_0001 (Unknowns Budget Policy Integration)
// Task: BUDGET-018 - Create `UnknownBudgetExceeded` notification event
// Description: Factory for creating budget exceeded notification events.
// -----------------------------------------------------------------------------
using System.Collections.Immutable;
using System.Text.Json.Nodes;
using StellaOps.Policy.Unknowns.Models;
namespace StellaOps.Policy.Unknowns.Events;
/// <summary>
/// Factory for creating budget exceeded notification events.
/// </summary>
public static class BudgetExceededEventFactory
{
/// <summary>
/// Event kind for budget exceeded (blocking).
/// </summary>
public const string BudgetExceededKind = "policy.budget.exceeded";
/// <summary>
/// Event kind for budget warning (non-blocking).
/// </summary>
public const string BudgetWarningKind = "policy.budget.warning";
/// <summary>
/// Creates a budget exceeded notification event payload.
/// </summary>
public static BudgetEventPayload CreatePayload(
string environment,
BudgetCheckResult result,
string? imageDigest = null,
string? policyRevisionId = null)
{
ArgumentNullException.ThrowIfNull(result);
var violations = result.Violations
.Select(kvp => new BudgetViolationInfo(
kvp.Key.ToString(),
GetShortCode(kvp.Key),
kvp.Value.Count,
kvp.Value.Limit))
.ToImmutableList();
return new BudgetEventPayload
{
Environment = environment,
IsWithinBudget = result.IsWithinBudget,
Action = result.RecommendedAction.ToString().ToLowerInvariant(),
TotalUnknowns = result.TotalUnknowns,
TotalLimit = result.TotalLimit,
ViolationCount = result.Violations.Count,
Violations = violations,
Message = result.Message,
ImageDigest = imageDigest,
PolicyRevisionId = policyRevisionId,
Timestamp = DateTimeOffset.UtcNow
};
}
/// <summary>
/// Converts the payload to a JsonNode for the notification event.
/// </summary>
public static JsonNode ToJsonNode(BudgetEventPayload payload)
{
ArgumentNullException.ThrowIfNull(payload);
var obj = new JsonObject
{
["environment"] = payload.Environment,
["isWithinBudget"] = payload.IsWithinBudget,
["action"] = payload.Action,
["totalUnknowns"] = payload.TotalUnknowns,
["violationCount"] = payload.ViolationCount,
["timestamp"] = payload.Timestamp.ToString("O")
};
if (payload.TotalLimit.HasValue)
{
obj["totalLimit"] = payload.TotalLimit.Value;
}
if (payload.Message is not null)
{
obj["message"] = payload.Message;
}
if (payload.ImageDigest is not null)
{
obj["imageDigest"] = payload.ImageDigest;
}
if (payload.PolicyRevisionId is not null)
{
obj["policyRevisionId"] = payload.PolicyRevisionId;
}
if (payload.Violations.Count > 0)
{
var violations = new JsonArray();
foreach (var v in payload.Violations)
{
violations.Add(new JsonObject
{
["reasonCode"] = v.ReasonCode,
["shortCode"] = v.ShortCode,
["count"] = v.Count,
["limit"] = v.Limit
});
}
obj["violations"] = violations;
}
return obj;
}
/// <summary>
/// Gets the event kind based on the budget action.
/// </summary>
public static string GetEventKind(BudgetAction action)
{
return action == BudgetAction.Block
? BudgetExceededKind
: BudgetWarningKind;
}
private static string GetShortCode(UnknownReasonCode code) => code switch
{
UnknownReasonCode.Reachability => "U-RCH",
UnknownReasonCode.Identity => "U-ID",
UnknownReasonCode.Provenance => "U-PROV",
UnknownReasonCode.VexConflict => "U-VEX",
UnknownReasonCode.FeedGap => "U-FEED",
UnknownReasonCode.ConfigUnknown => "U-CONFIG",
UnknownReasonCode.AnalyzerLimit => "U-ANALYZER",
_ => "U-UNK"
};
}
/// <summary>
/// Payload for budget exceeded/warning notification events.
/// </summary>
public sealed record BudgetEventPayload
{
/// <summary>
/// Environment where budget was exceeded.
/// </summary>
public required string Environment { get; init; }
/// <summary>
/// Whether the result is within budget.
/// </summary>
public required bool IsWithinBudget { get; init; }
/// <summary>
/// Recommended action: "warn" or "block".
/// </summary>
public required string Action { get; init; }
/// <summary>
/// Total unknown count.
/// </summary>
public required int TotalUnknowns { get; init; }
/// <summary>
/// Configured total limit.
/// </summary>
public int? TotalLimit { get; init; }
/// <summary>
/// Number of violations.
/// </summary>
public required int ViolationCount { get; init; }
/// <summary>
/// Violation details.
/// </summary>
public ImmutableList<BudgetViolationInfo> Violations { get; init; } = ImmutableList<BudgetViolationInfo>.Empty;
/// <summary>
/// Budget exceeded message.
/// </summary>
public string? Message { get; init; }
/// <summary>
/// Image digest if applicable.
/// </summary>
public string? ImageDigest { get; init; }
/// <summary>
/// Policy revision ID if applicable.
/// </summary>
public string? PolicyRevisionId { get; init; }
/// <summary>
/// Event timestamp.
/// </summary>
public DateTimeOffset Timestamp { get; init; } = DateTimeOffset.UtcNow;
}
/// <summary>
/// Information about a specific budget violation.
/// </summary>
public sealed record BudgetViolationInfo(
string ReasonCode,
string ShortCode,
int Count,
int Limit);