Add unit tests for AST parsing and security sink detection

- Created `StellaOps.AuditPack.Tests.csproj` for unit testing the AuditPack library.
- Implemented comprehensive unit tests in `index.test.js` for AST parsing, covering various JavaScript and TypeScript constructs including functions, classes, decorators, and JSX.
- Added `sink-detect.test.js` to test security sink detection patterns, validating command injection, SQL injection, file write, deserialization, SSRF, NoSQL injection, and more.
- Included tests for taint source detection in various contexts such as Express, Koa, and AWS Lambda.
This commit is contained in:
StellaOps Bot
2025-12-23 09:23:42 +02:00
parent 7e384ab610
commit 56e2dc01ee
96 changed files with 8555 additions and 1455 deletions

View File

@@ -27,8 +27,10 @@ public class CompareCommandTests
_services = new ServiceCollection()
.AddSingleton<ICompareClient, LocalCompareClient>()
.BuildServiceProvider();
_verboseOption = new Option<bool>("--verbose", "Enable verbose output");
_verboseOption.AddAlias("-v");
_verboseOption = new Option<bool>("--verbose", new[] { "-v" })
{
Description = "Enable verbose output"
};
_cancellationToken = CancellationToken.None;
}
@@ -212,10 +214,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare diff --base sha256:abc123 --target sha256:def456");
var result = root.Parse("compare diff --base sha256:abc123 --target sha256:def456");
// Assert
Assert.Empty(result.Errors);
@@ -227,10 +228,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare diff -b sha256:abc123 -t sha256:def456");
var result = root.Parse("compare diff -b sha256:abc123 -t sha256:def456");
// Assert
Assert.Empty(result.Errors);
@@ -242,10 +242,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare diff -b sha256:abc123 -t sha256:def456 -o json");
var result = root.Parse("compare diff -b sha256:abc123 -t sha256:def456 -o json");
// Assert
Assert.Empty(result.Errors);
@@ -257,10 +256,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare diff -b sha256:abc123 -t sha256:def456 -o sarif");
var result = root.Parse("compare diff -b sha256:abc123 -t sha256:def456 -o sarif");
// Assert
Assert.Empty(result.Errors);
@@ -272,10 +270,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare diff -b sha256:abc123 -t sha256:def456 -o json -f output.json");
var result = root.Parse("compare diff -b sha256:abc123 -t sha256:def456 -o json -f output.json");
// Assert
Assert.Empty(result.Errors);
@@ -287,10 +284,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare diff -b sha256:abc123 -t sha256:def456 -s critical");
var result = root.Parse("compare diff -b sha256:abc123 -t sha256:def456 -s critical");
// Assert
Assert.Empty(result.Errors);
@@ -302,10 +298,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare diff -b sha256:abc123 -t sha256:def456 --include-unchanged");
var result = root.Parse("compare diff -b sha256:abc123 -t sha256:def456 --include-unchanged");
// Assert
Assert.Empty(result.Errors);
@@ -317,10 +312,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare diff -t sha256:def456");
var result = root.Parse("compare diff -t sha256:def456");
// Assert
Assert.NotEmpty(result.Errors);
@@ -332,10 +326,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare diff -b sha256:abc123");
var result = root.Parse("compare diff -b sha256:abc123");
// Assert
Assert.NotEmpty(result.Errors);
@@ -347,10 +340,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare summary -b sha256:abc123 -t sha256:def456");
var result = root.Parse("compare summary -b sha256:abc123 -t sha256:def456");
// Assert
Assert.Empty(result.Errors);
@@ -362,10 +354,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare can-ship -b sha256:abc123 -t sha256:def456");
var result = root.Parse("compare can-ship -b sha256:abc123 -t sha256:def456");
// Assert
Assert.Empty(result.Errors);
@@ -377,10 +368,9 @@ public class CompareCommandTests
// Arrange
var command = CompareCommandBuilder.BuildCompareCommand(_services, _verboseOption, _cancellationToken);
var root = new RootCommand { command };
var parser = new Parser(root);
// Act
var result = parser.Parse("compare vulns -b sha256:abc123 -t sha256:def456");
var result = root.Parse("compare vulns -b sha256:abc123 -t sha256:def456");
// Assert
Assert.Empty(result.Errors);

View File

@@ -6,6 +6,7 @@
using System.CommandLine;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Xunit;
using StellaOps.Cli.Commands;
@@ -23,7 +24,7 @@ public class Sprint5100_CommandTests
var serviceCollection = new ServiceCollection();
serviceCollection.AddLogging(builder => builder.AddProvider(NullLoggerProvider.Instance));
_services = serviceCollection.BuildServiceProvider();
_verboseOption = new Option<bool>("--verbose", "-v") { Description = "Verbose output" };
_verboseOption = new Option<bool>("--verbose", new[] { "-v" }) { Description = "Verbose output" };
_cancellationToken = CancellationToken.None;
}

View File

@@ -20,9 +20,9 @@ public sealed class VerifyImageCommandTests
var verify = Assert.Single(root.Subcommands, command => string.Equals(command.Name, "verify", StringComparison.Ordinal));
var image = Assert.Single(verify.Subcommands, command => string.Equals(command.Name, "image", StringComparison.Ordinal));
Assert.Contains(image.Options, option => option.HasAlias("--require"));
Assert.Contains(image.Options, option => option.HasAlias("--trust-policy"));
Assert.Contains(image.Options, option => option.HasAlias("--output"));
Assert.Contains(image.Options, option => option.HasAlias("--strict"));
Assert.Contains(image.Options, option => option.Name == "--require" || option.Aliases.Contains("--require"));
Assert.Contains(image.Options, option => option.Name == "--trust-policy" || option.Aliases.Contains("--trust-policy"));
Assert.Contains(image.Options, option => option.Name == "--output" || option.Aliases.Contains("--output"));
Assert.Contains(image.Options, option => option.Name == "--strict" || option.Aliases.Contains("--strict"));
}
}

View File

@@ -69,9 +69,15 @@ public sealed class ImageAttestationVerifierTests
public Task<string> ResolveDigestAsync(OciImageReference reference, CancellationToken cancellationToken = default)
=> Task.FromResult(_digest);
public Task<string> ResolveTagAsync(string registry, string repository, string tag, CancellationToken cancellationToken = default)
=> Task.FromResult(_digest);
public Task<OciReferrersResponse> ListReferrersAsync(OciImageReference reference, string digest, CancellationToken cancellationToken = default)
=> Task.FromResult(_referrers);
public Task<IReadOnlyList<OciReferrerDescriptor>> GetReferrersAsync(string registry, string repository, string digest, string? artifactType = null, CancellationToken cancellationToken = default)
=> Task.FromResult<IReadOnlyList<OciReferrerDescriptor>>(_referrers.Referrers.Select(m => new OciReferrerDescriptor { Digest = m.Digest, ArtifactType = m.ArtifactType }).ToList());
public Task<OciManifest> GetManifestAsync(OciImageReference reference, string digest, CancellationToken cancellationToken = default)
=> Task.FromResult(new OciManifest());