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,114 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// BaselineEndpointsTests.cs
|
||||
// Sprint: SPRINT_4200_0002_0006_delta_compare_api
|
||||
// Description: Integration tests for baseline selection endpoints.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using StellaOps.Scanner.WebService.Contracts;
|
||||
|
||||
namespace StellaOps.Scanner.WebService.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Integration tests for baseline selection endpoints.
|
||||
/// </summary>
|
||||
public sealed class BaselineEndpointsTests
|
||||
{
|
||||
private static readonly JsonSerializerOptions SerializerOptions = new(JsonSerializerDefaults.Web);
|
||||
|
||||
[Fact]
|
||||
public async Task GetRecommendations_ValidDigest_ReturnsRecommendations()
|
||||
{
|
||||
using var factory = new ScannerApplicationFactory();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync("/api/v1/baselines/recommendations/sha256:artifact123");
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var result = await response.Content.ReadFromJsonAsync<BaselineRecommendationsResponseDto>(SerializerOptions);
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal("sha256:artifact123", result!.ArtifactDigest);
|
||||
Assert.NotEmpty(result.Recommendations);
|
||||
Assert.Contains(result.Recommendations, r => r.IsDefault);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRecommendations_WithEnvironment_FiltersCorrectly()
|
||||
{
|
||||
using var factory = new ScannerApplicationFactory();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync("/api/v1/baselines/recommendations/sha256:artifact123?environment=production");
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var result = await response.Content.ReadFromJsonAsync<BaselineRecommendationsResponseDto>(SerializerOptions);
|
||||
Assert.NotNull(result);
|
||||
Assert.NotEmpty(result!.Recommendations);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRecommendations_IncludesRationale()
|
||||
{
|
||||
using var factory = new ScannerApplicationFactory();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync("/api/v1/baselines/recommendations/sha256:artifact123");
|
||||
var result = await response.Content.ReadFromJsonAsync<BaselineRecommendationsResponseDto>(SerializerOptions);
|
||||
|
||||
Assert.NotNull(result);
|
||||
foreach (var rec in result!.Recommendations)
|
||||
{
|
||||
Assert.NotEmpty(rec.Rationale);
|
||||
Assert.NotEmpty(rec.Type);
|
||||
Assert.NotEmpty(rec.Label);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRationale_ValidDigests_ReturnsDetailedRationale()
|
||||
{
|
||||
using var factory = new ScannerApplicationFactory();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync("/api/v1/baselines/rationale/sha256:base123/sha256:head456");
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var result = await response.Content.ReadFromJsonAsync<BaselineRationaleResponseDto>(SerializerOptions);
|
||||
Assert.NotNull(result);
|
||||
Assert.Equal("sha256:base123", result!.BaseDigest);
|
||||
Assert.Equal("sha256:head456", result.HeadDigest);
|
||||
Assert.NotEmpty(result.SelectionType);
|
||||
Assert.NotEmpty(result.Rationale);
|
||||
Assert.NotEmpty(result.DetailedExplanation);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRationale_IncludesSelectionCriteria()
|
||||
{
|
||||
using var factory = new ScannerApplicationFactory();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync("/api/v1/baselines/rationale/sha256:baseline-base123/sha256:head456");
|
||||
var result = await response.Content.ReadFromJsonAsync<BaselineRationaleResponseDto>(SerializerOptions);
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.NotNull(result!.SelectionCriteria);
|
||||
Assert.NotEmpty(result.SelectionCriteria);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRecommendations_DefaultIsFirst()
|
||||
{
|
||||
using var factory = new ScannerApplicationFactory();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var response = await client.GetAsync("/api/v1/baselines/recommendations/sha256:artifact123");
|
||||
var result = await response.Content.ReadFromJsonAsync<BaselineRecommendationsResponseDto>(SerializerOptions);
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.NotEmpty(result!.Recommendations);
|
||||
Assert.True(result.Recommendations[0].IsDefault);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user