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:
@@ -32,6 +32,8 @@ public static class DeltaCommandGroup
|
||||
delta.Add(BuildComputeCommand(verboseOption, cancellationToken));
|
||||
delta.Add(BuildCheckCommand(verboseOption, cancellationToken));
|
||||
delta.Add(BuildAttachCommand(verboseOption, cancellationToken));
|
||||
delta.Add(BuildVerifyCommand(verboseOption, cancellationToken));
|
||||
delta.Add(BuildPushCommand(verboseOption, cancellationToken));
|
||||
|
||||
return delta;
|
||||
}
|
||||
@@ -219,4 +221,136 @@ public static class DeltaCommandGroup
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Command BuildVerifyCommand(Option<bool> verboseOption, CancellationToken cancellationToken)
|
||||
{
|
||||
var deltaOption = new Option<string>("--delta") { Description = "Delta verdict JSON file", Required = true };
|
||||
var keyIdOption = new Option<string?>("--key-id") { Description = "Signing key identifier" };
|
||||
var secretOption = new Option<string?>("--secret") { Description = "Base64 secret for HMAC verification" };
|
||||
var outputOption = new Option<string?>("--output") { Description = "Output format (text|json)", Arity = ArgumentArity.ZeroOrOne };
|
||||
|
||||
var verify = new Command("verify", "Verify delta verdict signature");
|
||||
verify.Add(deltaOption);
|
||||
verify.Add(keyIdOption);
|
||||
verify.Add(secretOption);
|
||||
verify.Add(outputOption);
|
||||
verify.Add(verboseOption);
|
||||
|
||||
verify.SetAction(async (parseResult, _) =>
|
||||
{
|
||||
var deltaPath = parseResult.GetValue(deltaOption) ?? string.Empty;
|
||||
var keyId = parseResult.GetValue(keyIdOption) ?? "delta-dev";
|
||||
var secret = parseResult.GetValue(secretOption);
|
||||
var outputFormat = parseResult.GetValue(outputOption) ?? "text";
|
||||
|
||||
var delta = DeltaVerdictSerializer.Deserialize(await File.ReadAllTextAsync(deltaPath, cancellationToken));
|
||||
|
||||
var signer = new DeltaSigningService();
|
||||
var result = await signer.VerifyAsync(delta, new VerificationOptions
|
||||
{
|
||||
KeyId = keyId,
|
||||
SecretBase64 = secret ?? Convert.ToBase64String("delta-dev-secret"u8.ToArray())
|
||||
}, cancellationToken);
|
||||
|
||||
if (string.Equals(outputFormat, "json", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Console.WriteLine(JsonSerializer.Serialize(new
|
||||
{
|
||||
isValid = result.IsValid,
|
||||
error = result.Error,
|
||||
deltaDigest = delta.DeltaDigest
|
||||
}, JsonOptions));
|
||||
}
|
||||
else
|
||||
{
|
||||
var status = result.IsValid ? "[PASS]" : "[FAIL]";
|
||||
Console.WriteLine($"{status} Delta Signature Verification");
|
||||
Console.WriteLine($" Delta Digest: {delta.DeltaDigest ?? "N/A"}");
|
||||
Console.WriteLine($" Valid: {result.IsValid}");
|
||||
if (!string.IsNullOrEmpty(result.Error))
|
||||
{
|
||||
Console.WriteLine($" Error: {result.Error}");
|
||||
}
|
||||
}
|
||||
|
||||
return result.IsValid ? 0 : 1;
|
||||
});
|
||||
|
||||
return verify;
|
||||
}
|
||||
|
||||
private static Command BuildPushCommand(Option<bool> verboseOption, CancellationToken cancellationToken)
|
||||
{
|
||||
var deltaOption = new Option<string>("--delta") { Description = "Delta verdict JSON file", Required = true };
|
||||
var targetOption = new Option<string>("--target") { Description = "Target OCI artifact reference (e.g., registry.example.com/repo:tag)", Required = true };
|
||||
var dryRunOption = new Option<bool>("--dry-run") { Description = "Preview push without executing" };
|
||||
var outputOption = new Option<string?>("--output") { Description = "Output format (text|json)" };
|
||||
|
||||
var push = new Command("push", "Push delta verdict to OCI registry as referrer");
|
||||
push.Add(deltaOption);
|
||||
push.Add(targetOption);
|
||||
push.Add(dryRunOption);
|
||||
push.Add(outputOption);
|
||||
push.Add(verboseOption);
|
||||
|
||||
push.SetAction(async (parseResult, _) =>
|
||||
{
|
||||
var deltaPath = parseResult.GetValue(deltaOption) ?? string.Empty;
|
||||
var targetRef = parseResult.GetValue(targetOption) ?? string.Empty;
|
||||
var dryRun = parseResult.GetValue(dryRunOption);
|
||||
var outputFormat = parseResult.GetValue(outputOption) ?? "text";
|
||||
|
||||
var delta = DeltaVerdictSerializer.Deserialize(await File.ReadAllTextAsync(deltaPath, cancellationToken));
|
||||
var attacher = new DeltaOciAttacher();
|
||||
var attachment = attacher.CreateAttachment(delta, targetRef);
|
||||
|
||||
if (dryRun)
|
||||
{
|
||||
if (string.Equals(outputFormat, "json", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Console.WriteLine(JsonSerializer.Serialize(new
|
||||
{
|
||||
dryRun = true,
|
||||
artifact = attachment.ArtifactReference,
|
||||
mediaType = attachment.MediaType,
|
||||
payloadSize = attachment.Payload.Length,
|
||||
annotations = attachment.Annotations
|
||||
}, JsonOptions));
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("[DRY-RUN] Delta OCI Push");
|
||||
Console.WriteLine($" Target: {attachment.ArtifactReference}");
|
||||
Console.WriteLine($" MediaType: {attachment.MediaType}");
|
||||
Console.WriteLine($" PayloadSize: {attachment.Payload.Length} bytes");
|
||||
Console.WriteLine($" Annotations:");
|
||||
foreach (var (key, value) in attachment.Annotations)
|
||||
{
|
||||
Console.WriteLine($" {key}: {value}");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// For actual push, we need to use the OCI pusher infrastructure
|
||||
// This would require DI container setup; for CLI direct usage, output the attachment info
|
||||
if (string.Equals(outputFormat, "json", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Console.WriteLine(JsonSerializer.Serialize(attachment, JsonOptions));
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Delta OCI Push Prepared");
|
||||
Console.WriteLine($" Target: {attachment.ArtifactReference}");
|
||||
Console.WriteLine($" MediaType: {attachment.MediaType}");
|
||||
Console.WriteLine($" PayloadSize: {attachment.Payload.Length} bytes");
|
||||
Console.WriteLine(" Use 'oras push' or OCI-compliant tooling to complete the push.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return push;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user