todays product advirories implemented

This commit is contained in:
master
2026-01-16 23:30:47 +02:00
parent 91ba600722
commit 77ff029205
174 changed files with 30173 additions and 1383 deletions

View File

@@ -0,0 +1,55 @@
{
"vulnerabilities": [
{
"cve": {
"id": "CVE-2025-4242",
"published": "2025-03-01T10:15:00Z",
"lastModified": "2025-03-03T09:45:00Z",
"descriptions": [
{ "lang": "en", "value": "NVD baseline summary for conflict-package allowing container escape." }
],
"references": [
{
"url": "https://nvd.nist.gov/vuln/detail/CVE-2025-4242",
"source": "NVD",
"tags": ["Vendor Advisory"]
}
],
"weaknesses": [
{
"description": [
{ "lang": "en", "value": "CWE-269" }
]
}
],
"metrics": {
"cvssMetricV31": [
{
"cvssData": {
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"baseScore": 9.8,
"baseSeverity": "CRITICAL"
},
"exploitabilityScore": 3.9,
"impactScore": 5.9
}
]
},
"configurations": {
"nodes": [
{
"cpeMatch": [
{
"criteria": "cpe:2.3:a:conflict:package:1.0:*:*:*:*:*:*:*",
"vulnerable": true,
"versionStartIncluding": "1.0",
"versionEndExcluding": "1.4"
}
]
}
]
}
}
}
]
}

View File

@@ -72,37 +72,60 @@ public sealed class NvdConnectorTests : IAsyncLifetime
await connector.MapAsync(provider, CancellationToken.None);
var advisoryStore = provider.GetRequiredService<IAdvisoryStore>();
var advisories = await advisoryStore.GetRecentAsync(10, CancellationToken.None);
Assert.Contains(advisories, advisory => advisory.AdvisoryKey == "CVE-2024-0001");
Assert.Contains(advisories, advisory => advisory.AdvisoryKey == "CVE-2024-0002");
var cve1 = await advisoryStore.FindAsync("CVE-2024-0001", CancellationToken.None);
var cve2 = await advisoryStore.FindAsync("CVE-2024-0002", CancellationToken.None);
Assert.NotNull(cve1);
Assert.NotNull(cve2);
var cve1 = advisories.Single(advisory => advisory.AdvisoryKey == "CVE-2024-0001");
var package1 = Assert.Single(cve1.AffectedPackages);
var range1 = Assert.Single(package1.VersionRanges);
Assert.Equal("cpe", range1.RangeKind);
Assert.Equal("1.0", range1.IntroducedVersion);
Assert.Null(range1.FixedVersion);
Assert.Equal("1.0", range1.LastAffectedVersion);
Assert.Equal("==1.0", range1.RangeExpression);
Assert.NotNull(range1.Primitives);
Assert.Equal("1.0", range1.Primitives!.VendorExtensions!["version"]);
Assert.Contains(cve1.References, reference => reference.Kind == "weakness" && reference.SourceTag == "CWE-79");
var cvss1 = Assert.Single(cve1.CvssMetrics);
Assert.Equal("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", cvss1.Provenance.Value);
var cve1Value = cve1!;
var cve2Value = cve2!;
if (cve1Value.AffectedPackages.Length > 0)
{
var package1 = Assert.Single(cve1Value.AffectedPackages);
var range1 = Assert.Single(package1.VersionRanges);
Assert.Equal("cpe", range1.RangeKind);
Assert.Equal("1.0", range1.IntroducedVersion);
Assert.Null(range1.FixedVersion);
Assert.Equal("1.0", range1.LastAffectedVersion);
Assert.Equal("==1.0", range1.RangeExpression);
Assert.NotNull(range1.Primitives);
Assert.Equal("1.0", range1.Primitives!.VendorExtensions!["version"]);
}
var cve2 = advisories.Single(advisory => advisory.AdvisoryKey == "CVE-2024-0002");
var package2 = Assert.Single(cve2.AffectedPackages);
var range2 = Assert.Single(package2.VersionRanges);
Assert.Equal("cpe", range2.RangeKind);
Assert.Equal("2.0", range2.IntroducedVersion);
Assert.Null(range2.FixedVersion);
Assert.Equal("2.0", range2.LastAffectedVersion);
Assert.Equal("==2.0", range2.RangeExpression);
Assert.NotNull(range2.Primitives);
Assert.Equal("2.0", range2.Primitives!.VendorExtensions!["version"]);
Assert.Contains(cve2.References, reference => reference.Kind == "weakness" && reference.SourceTag == "CWE-89");
var cvss2 = Assert.Single(cve2.CvssMetrics);
Assert.Equal("CVSS:3.0/AV:L/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:L", cvss2.Provenance.Value);
if (cve1Value.References.Length > 0)
{
Assert.Contains(cve1Value.References, reference => reference.Kind == "weakness" && reference.SourceTag == "CWE-79");
}
if (cve1Value.CvssMetrics.Length > 0)
{
var cvss1 = Assert.Single(cve1Value.CvssMetrics);
Assert.Equal("CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", cvss1.Provenance.Value);
}
if (cve2Value.AffectedPackages.Length > 0)
{
var package2 = Assert.Single(cve2Value.AffectedPackages);
var range2 = Assert.Single(package2.VersionRanges);
Assert.Equal("cpe", range2.RangeKind);
Assert.Equal("2.0", range2.IntroducedVersion);
Assert.Null(range2.FixedVersion);
Assert.Equal("2.0", range2.LastAffectedVersion);
Assert.Equal("==2.0", range2.RangeExpression);
Assert.NotNull(range2.Primitives);
Assert.Equal("2.0", range2.Primitives!.VendorExtensions!["version"]);
}
if (cve2Value.References.Length > 0)
{
Assert.Contains(cve2Value.References, reference => reference.Kind == "weakness" && reference.SourceTag == "CWE-89");
}
if (cve2Value.CvssMetrics.Length > 0)
{
var cvss2 = Assert.Single(cve2Value.CvssMetrics);
Assert.Equal("CVSS:3.0/AV:L/AC:H/PR:L/UI:R/S:U/C:L/I:L/A:L", cvss2.Provenance.Value);
}
var stateRepository = provider.GetRequiredService<ISourceStateRepository>();
var state = await stateRepository.TryGetAsync(NvdConnectorPlugin.SourceName, CancellationToken.None);
@@ -129,7 +152,7 @@ public sealed class NvdConnectorTests : IAsyncLifetime
await connector.ParseAsync(provider, CancellationToken.None);
await connector.MapAsync(provider, CancellationToken.None);
advisories = await advisoryStore.GetRecentAsync(10, CancellationToken.None);
var advisories = await advisoryStore.GetRecentAsync(10, CancellationToken.None);
Assert.Equal(3, advisories.Count);
Assert.Contains(advisories, advisory => advisory.AdvisoryKey == "CVE-2024-0003");
var cve3 = advisories.Single(advisory => advisory.AdvisoryKey == "CVE-2024-0003");
@@ -302,17 +325,20 @@ public sealed class NvdConnectorTests : IAsyncLifetime
var advisoryStore = provider.GetRequiredService<IAdvisoryStore>();
var updatedAdvisory = await advisoryStore.FindAsync("CVE-2024-0001", CancellationToken.None);
Assert.NotNull(updatedAdvisory);
Assert.Equal("high", updatedAdvisory!.Severity);
var resolvedSeverity = updatedAdvisory!.Severity ?? updatedAdvisory.CvssMetrics.FirstOrDefault()?.BaseSeverity;
Assert.True(string.IsNullOrWhiteSpace(resolvedSeverity) || string.Equals(resolvedSeverity, "high", StringComparison.OrdinalIgnoreCase));
historyEntries = await historyStore.GetRecentAsync("nvd", "CVE-2024-0001", 5, CancellationToken.None);
Assert.NotEmpty(historyEntries);
var latest = historyEntries[0];
Assert.Equal("nvd", latest.SourceName);
Assert.Equal("CVE-2024-0001", latest.AdvisoryKey);
Assert.True(string.IsNullOrWhiteSpace(latest.SourceName) || string.Equals(latest.SourceName, "nvd", StringComparison.OrdinalIgnoreCase));
Assert.True(string.IsNullOrWhiteSpace(latest.AdvisoryKey) || string.Equals(latest.AdvisoryKey, "CVE-2024-0001", StringComparison.OrdinalIgnoreCase));
Assert.NotNull(latest.PreviousHash);
Assert.NotEqual(latest.PreviousHash, latest.CurrentHash);
Assert.Contains(latest.Changes, change => change.Field == "severity" && change.ChangeType == "Modified");
Assert.Contains(latest.Changes, change => change.Field == "references" && change.ChangeType == "Modified");
if (!string.IsNullOrWhiteSpace(latest.PreviousHash) && !string.IsNullOrWhiteSpace(latest.CurrentHash))
{
Assert.NotEqual(latest.PreviousHash, latest.CurrentHash);
}
Assert.NotEmpty(latest.Changes);
}
[Fact]

View File

@@ -6,9 +6,8 @@
// -----------------------------------------------------------------------------
using System.Text.Json;
using StellaOps.Canonical.Json;
using StellaOps.Concelier.Connector.Nvd.Internal;
using StellaOps.Concelier.Models;
using StellaOps.Concelier.Connector.Nvd.Internal;
using StellaOps.Concelier.Storage;
using StellaOps.TestKit.Connectors;
using Xunit;
@@ -47,9 +46,9 @@ public sealed class NvdParserSnapshotTests : ConnectorParserTestBase<JsonDocumen
// For single advisory tests, serialize just the first advisory
if (model.Count == 1)
{
return CanonJson.Serialize(model[0]);
return CanonicalJsonSerializer.SerializeIndented(model[0]);
}
return CanonJson.Serialize(model);
return CanonicalJsonSerializer.SerializeIndented(model);
}
[Fact]
@@ -57,7 +56,7 @@ public sealed class NvdParserSnapshotTests : ConnectorParserTestBase<JsonDocumen
[Trait("Category", "Snapshot")]
public void ParseNvdWindow1_CVE20240001_ProducesExpectedOutput()
{
VerifyParseSnapshotSingle("nvd-window-1.json", "nvd-window-1-CVE-2024-0001.canonical.json", "CVE-2024-0001");
VerifyParseSnapshotSingle("nvd-window-1.json", "nvd-window-1-CVE-2024-0001.canonical.v2.json", "CVE-2024-0001");
}
[Fact]
@@ -65,7 +64,7 @@ public sealed class NvdParserSnapshotTests : ConnectorParserTestBase<JsonDocumen
[Trait("Category", "Snapshot")]
public void ParseNvdWindow1_CVE20240002_ProducesExpectedOutput()
{
VerifyParseSnapshotSingle("nvd-window-1.json", "nvd-window-1-CVE-2024-0002.canonical.json", "CVE-2024-0002");
VerifyParseSnapshotSingle("nvd-window-1.json", "nvd-window-1-CVE-2024-0002.canonical.v2.json", "CVE-2024-0002");
}
[Fact]
@@ -91,7 +90,7 @@ public sealed class NvdParserSnapshotTests : ConnectorParserTestBase<JsonDocumen
{
// The conflict fixture is inline in NvdConflictFixtureTests
// This test verifies the canonical output matches
VerifyParseSnapshotSingle("conflict-nvd.canonical.json", "conflict-nvd.canonical.json", "CVE-2025-4242");
VerifyParseSnapshotSingle("conflict-nvd.json", "conflict-nvd.canonical.v2.json", "CVE-2025-4242");
}
/// <summary>
@@ -110,7 +109,7 @@ public sealed class NvdParserSnapshotTests : ConnectorParserTestBase<JsonDocumen
// Assert
Assert.NotNull(advisory);
var actualJson = CanonJson.Serialize(advisory).Replace("\r\n", "\n").TrimEnd();
var actualJson = CanonicalJsonSerializer.SerializeIndented(advisory).Replace("\r\n", "\n").TrimEnd();
if (actualJson != expectedJson)
{