Add comprehensive security tests for OWASP A02, A05, A07, and A08 categories
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Lighthouse CI / Lighthouse Audit (push) Has been cancelled
Lighthouse CI / Axe Accessibility Audit (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Lighthouse CI / Lighthouse Audit (push) Has been cancelled
Lighthouse CI / Axe Accessibility Audit (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
- Implemented tests for Cryptographic Failures (A02) to ensure proper handling of sensitive data, secure algorithms, and key management. - Added tests for Security Misconfiguration (A05) to validate production configurations, security headers, CORS settings, and feature management. - Developed tests for Authentication Failures (A07) to enforce strong password policies, rate limiting, session management, and MFA support. - Created tests for Software and Data Integrity Failures (A08) to verify artifact signatures, SBOM integrity, attestation chains, and feed updates.
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
// =============================================================================
|
||||
// SpdxParserTests.cs
|
||||
// Golden-file tests for SPDX SBOM parsing
|
||||
// Part of Task T24: Golden-file tests for determinism
|
||||
// =============================================================================
|
||||
|
||||
using FluentAssertions;
|
||||
using StellaOps.AirGap.Importer.Reconciliation;
|
||||
using StellaOps.AirGap.Importer.Reconciliation.Parsers;
|
||||
|
||||
namespace StellaOps.AirGap.Importer.Tests.Reconciliation;
|
||||
|
||||
public sealed class SpdxParserTests
|
||||
{
|
||||
private static readonly string FixturesPath = Path.Combine(
|
||||
AppDomain.CurrentDomain.BaseDirectory,
|
||||
"Reconciliation", "Fixtures");
|
||||
|
||||
[Fact]
|
||||
public async Task ParseAsync_ValidSpdx_ExtractsAllSubjects()
|
||||
{
|
||||
// Arrange
|
||||
var parser = new SpdxParser();
|
||||
var filePath = Path.Combine(FixturesPath, "sample.spdx.json");
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Act
|
||||
var result = await parser.ParseAsync(filePath);
|
||||
|
||||
// Assert
|
||||
result.IsSuccess.Should().BeTrue();
|
||||
result.Format.Should().Be(SbomFormat.Spdx);
|
||||
result.SpecVersion.Should().Be("2.3");
|
||||
result.SerialNumber.Should().Be("https://example.com/test-app/1.0.0");
|
||||
result.GeneratorTool.Should().Contain("syft");
|
||||
|
||||
// Should have 3 packages with SHA256 checksums
|
||||
result.Subjects.Should().HaveCount(3);
|
||||
|
||||
// Verify subjects are sorted by digest
|
||||
result.Subjects.Should().BeInAscendingOrder(s => s.Digest, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ParseAsync_ExtractsPrimarySubject()
|
||||
{
|
||||
// Arrange
|
||||
var parser = new SpdxParser();
|
||||
var filePath = Path.Combine(FixturesPath, "sample.spdx.json");
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Act
|
||||
var result = await parser.ParseAsync(filePath);
|
||||
|
||||
// Assert
|
||||
result.PrimarySubject.Should().NotBeNull();
|
||||
result.PrimarySubject!.Name.Should().Be("test-app");
|
||||
result.PrimarySubject.Version.Should().Be("1.0.0");
|
||||
result.PrimarySubject.SpdxId.Should().Be("SPDXRef-Package-test-app");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ParseAsync_ExtractsPurls()
|
||||
{
|
||||
// Arrange
|
||||
var parser = new SpdxParser();
|
||||
var filePath = Path.Combine(FixturesPath, "sample.spdx.json");
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Act
|
||||
var result = await parser.ParseAsync(filePath);
|
||||
|
||||
// Assert - check for components with purls
|
||||
var zlib = result.Subjects.FirstOrDefault(s => s.Name == "zlib");
|
||||
zlib.Should().NotBeNull();
|
||||
zlib!.Purl.Should().Be("pkg:generic/zlib@1.2.11");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ParseAsync_SubjectDigestsAreNormalized()
|
||||
{
|
||||
// Arrange
|
||||
var parser = new SpdxParser();
|
||||
var filePath = Path.Combine(FixturesPath, "sample.spdx.json");
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Act
|
||||
var result = await parser.ParseAsync(filePath);
|
||||
|
||||
// Assert - all digests should be normalized sha256:lowercase format
|
||||
foreach (var subject in result.Subjects)
|
||||
{
|
||||
subject.Digest.Should().StartWith("sha256:");
|
||||
subject.Digest[7..].Should().MatchRegex("^[a-f0-9]{64}$");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectFormat_SpdxFile_ReturnsSpdx()
|
||||
{
|
||||
var parser = new SpdxParser();
|
||||
parser.DetectFormat("test.spdx.json").Should().Be(SbomFormat.Spdx);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectFormat_NonSpdxFile_ReturnsUnknown()
|
||||
{
|
||||
var parser = new SpdxParser();
|
||||
parser.DetectFormat("test.cdx.json").Should().Be(SbomFormat.Unknown);
|
||||
parser.DetectFormat("test.json").Should().Be(SbomFormat.Unknown);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ParseAsync_Deterministic_SameOutputForSameInput()
|
||||
{
|
||||
// Arrange
|
||||
var parser = new SpdxParser();
|
||||
var filePath = Path.Combine(FixturesPath, "sample.spdx.json");
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Act - parse twice
|
||||
var result1 = await parser.ParseAsync(filePath);
|
||||
var result2 = await parser.ParseAsync(filePath);
|
||||
|
||||
// Assert - results should be identical and in same order
|
||||
result1.Subjects.Select(s => s.Digest).Should().Equal(result2.Subjects.Select(s => s.Digest));
|
||||
result1.Subjects.Select(s => s.Name).Should().Equal(result2.Subjects.Select(s => s.Name));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user