Add SBOM, symbols, traces, and VEX files for CVE-2022-21661 SQLi case
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Created CycloneDX and SPDX SBOM files for both reachable and unreachable images. - Added symbols.json detailing function entry and sink points in the WordPress code. - Included runtime traces for function calls in both reachable and unreachable scenarios. - Developed OpenVEX files indicating vulnerability status and justification for both cases. - Updated README for evaluator harness to guide integration with scanner output.
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using StellaOps.Concelier.Exporter.Json;
|
||||
using StellaOps.Concelier.Models;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using StellaOps.Concelier.Exporter.Json;
|
||||
using StellaOps.Concelier.Models;
|
||||
using StellaOps.Cryptography;
|
||||
|
||||
namespace StellaOps.Concelier.Exporter.Json.Tests;
|
||||
|
||||
@@ -82,26 +83,52 @@ public sealed class JsonExportSnapshotBuilderTests : IDisposable
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsync_NormalizesInputOrdering()
|
||||
{
|
||||
var options = new JsonExportOptions { OutputRoot = _root };
|
||||
var builder = new JsonExportSnapshotBuilder(options, new VulnListJsonExportPathResolver());
|
||||
var exportedAt = DateTimeOffset.Parse("2024-06-01T00:00:00Z", CultureInfo.InvariantCulture);
|
||||
public async Task WriteAsync_NormalizesInputOrdering()
|
||||
{
|
||||
var options = new JsonExportOptions { OutputRoot = _root };
|
||||
var builder = new JsonExportSnapshotBuilder(options, new VulnListJsonExportPathResolver());
|
||||
var exportedAt = DateTimeOffset.Parse("2024-06-01T00:00:00Z", CultureInfo.InvariantCulture);
|
||||
|
||||
var advisoryA = CreateAdvisory("CVE-2024-1000", new[] { "CVE-2024-1000" }, "Alpha", "high");
|
||||
var advisoryB = CreateAdvisory("VENDOR-0001", new[] { "VENDOR-0001" }, "Vendor Advisory", "medium");
|
||||
|
||||
var result = await builder.WriteAsync(new[] { advisoryB, advisoryA }, exportedAt, cancellationToken: CancellationToken.None);
|
||||
|
||||
var expectedOrder = result.FilePaths.OrderBy(path => path, StringComparer.Ordinal).ToArray();
|
||||
Assert.Equal(expectedOrder, result.FilePaths.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsync_EnumeratesStreamOnlyOnce()
|
||||
{
|
||||
var options = new JsonExportOptions { OutputRoot = _root };
|
||||
var builder = new JsonExportSnapshotBuilder(options, new VulnListJsonExportPathResolver());
|
||||
var expectedOrder = result.FilePaths.OrderBy(path => path, StringComparer.Ordinal).ToArray();
|
||||
Assert.Equal(expectedOrder, result.FilePaths.ToArray());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsync_DifferentInputOrderProducesSameDigest()
|
||||
{
|
||||
var options = new JsonExportOptions { OutputRoot = _root };
|
||||
var builder = new JsonExportSnapshotBuilder(options, new VulnListJsonExportPathResolver());
|
||||
var exportedAt = DateTimeOffset.Parse("2024-06-15T00:00:00Z", CultureInfo.InvariantCulture);
|
||||
|
||||
var advisoryA = CreateAdvisory("CVE-2024-1100", new[] { "CVE-2024-1100" }, "Alpha", "critical");
|
||||
var advisoryB = CreateAdvisory("VENDOR-2024-42", new[] { "VENDOR-2024-42" }, "Vendor", "medium");
|
||||
|
||||
var first = await builder.WriteAsync(
|
||||
new[] { advisoryA, advisoryB },
|
||||
exportedAt,
|
||||
exportName: "order-a",
|
||||
cancellationToken: CancellationToken.None);
|
||||
var second = await builder.WriteAsync(
|
||||
new[] { advisoryB, advisoryA },
|
||||
exportedAt,
|
||||
exportName: "order-b",
|
||||
cancellationToken: CancellationToken.None);
|
||||
|
||||
Assert.Equal(
|
||||
Convert.ToHexString(ComputeDigest(first)),
|
||||
Convert.ToHexString(ComputeDigest(second)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteAsync_EnumeratesStreamOnlyOnce()
|
||||
{
|
||||
var options = new JsonExportOptions { OutputRoot = _root };
|
||||
var builder = new JsonExportSnapshotBuilder(options, new VulnListJsonExportPathResolver());
|
||||
var exportedAt = DateTimeOffset.Parse("2024-08-01T00:00:00Z", CultureInfo.InvariantCulture);
|
||||
|
||||
var advisories = new[]
|
||||
@@ -150,19 +177,20 @@ public sealed class JsonExportSnapshotBuilderTests : IDisposable
|
||||
});
|
||||
}
|
||||
|
||||
private static byte[] ComputeDigest(JsonExportResult result)
|
||||
{
|
||||
using var sha256 = SHA256.Create();
|
||||
foreach (var relative in result.FilePaths.OrderBy(x => x, StringComparer.Ordinal))
|
||||
{
|
||||
var fullPath = ResolvePath(result.ExportDirectory, relative);
|
||||
var bytes = File.ReadAllBytes(fullPath);
|
||||
sha256.TransformBlock(bytes, 0, bytes.Length, null, 0);
|
||||
}
|
||||
|
||||
sha256.TransformFinalBlock(Array.Empty<byte>(), 0, 0);
|
||||
return sha256.Hash ?? Array.Empty<byte>();
|
||||
}
|
||||
private static byte[] ComputeDigest(JsonExportResult result)
|
||||
{
|
||||
var hash = CryptoHashFactory.CreateDefault();
|
||||
var buffer = new ArrayBufferWriter<byte>();
|
||||
|
||||
foreach (var relative in result.FilePaths.OrderBy(x => x, StringComparer.Ordinal))
|
||||
{
|
||||
var fullPath = ResolvePath(result.ExportDirectory, relative);
|
||||
var bytes = File.ReadAllBytes(fullPath);
|
||||
buffer.Write(bytes);
|
||||
}
|
||||
|
||||
return hash.ComputeHash(buffer.WrittenSpan, HashAlgorithms.Sha256);
|
||||
}
|
||||
|
||||
private static string ResolvePath(string root, string relative)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,8 @@ using StellaOps.Concelier.Exporter.Json;
|
||||
using StellaOps.Concelier.Storage.Mongo.Advisories;
|
||||
using StellaOps.Concelier.Storage.Mongo.Exporting;
|
||||
using StellaOps.Concelier.Models;
|
||||
using StellaOps.Cryptography;
|
||||
using StellaOps.Cryptography.DependencyInjection;
|
||||
|
||||
namespace StellaOps.Concelier.Exporter.Json.Tests;
|
||||
|
||||
@@ -26,7 +28,10 @@ public sealed class JsonExporterDependencyInjectionRoutineTests
|
||||
services.AddSingleton<IAdvisoryStore, StubAdvisoryStore>();
|
||||
services.AddSingleton<IExportStateStore, StubExportStateStore>();
|
||||
services.AddSingleton<IAdvisoryEventLog, StubAdvisoryEventLog>();
|
||||
services.AddOptions();
|
||||
services.AddOptions<JobSchedulerOptions>();
|
||||
services.Configure<CryptoHashOptions>(_ => { });
|
||||
services.AddStellaOpsCrypto();
|
||||
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>())
|
||||
|
||||
@@ -10,16 +10,17 @@ using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using StellaOps.Concelier.Core.Events;
|
||||
using StellaOps.Concelier.Exporter.Json;
|
||||
using StellaOps.Concelier.Models;
|
||||
using StellaOps.Concelier.Storage.Mongo.Advisories;
|
||||
using StellaOps.Concelier.Storage.Mongo.Exporting;
|
||||
using StellaOps.Cryptography;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MongoDB.Driver;
|
||||
using StellaOps.Concelier.Core.Events;
|
||||
using StellaOps.Concelier.Exporter.Json;
|
||||
using StellaOps.Concelier.Models;
|
||||
using StellaOps.Concelier.Storage.Mongo.Advisories;
|
||||
using StellaOps.Concelier.Storage.Mongo.Exporting;
|
||||
using StellaOps.Cryptography;
|
||||
using StellaOps.Cryptography.DependencyInjection;
|
||||
|
||||
namespace StellaOps.Concelier.Exporter.Json.Tests;
|
||||
|
||||
@@ -70,7 +71,7 @@ public sealed class JsonFeedExporterTests : IDisposable
|
||||
NullLogger<JsonFeedExporter>.Instance,
|
||||
timeProvider);
|
||||
|
||||
using var provider = new ServiceCollection().BuildServiceProvider();
|
||||
using var provider = CreateCryptoProvider();
|
||||
await exporter.ExportAsync(provider, CancellationToken.None);
|
||||
|
||||
var record = await stateStore.FindAsync(JsonFeedExporter.ExporterId, CancellationToken.None);
|
||||
@@ -164,7 +165,7 @@ public sealed class JsonFeedExporterTests : IDisposable
|
||||
NullLogger<JsonFeedExporter>.Instance,
|
||||
timeProvider);
|
||||
|
||||
using var provider = new ServiceCollection().BuildServiceProvider();
|
||||
using var provider = CreateCryptoProvider();
|
||||
await exporter.ExportAsync(provider, CancellationToken.None);
|
||||
|
||||
var exportId = exportedAt.ToString(optionsValue.DirectoryNameFormat, CultureInfo.InvariantCulture);
|
||||
@@ -322,16 +323,7 @@ public sealed class JsonFeedExporterTests : IDisposable
|
||||
NullLogger<JsonFeedExporter>.Instance,
|
||||
timeProvider);
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<DefaultCryptoProvider>();
|
||||
services.AddSingleton<ICryptoProvider>(sp => sp.GetRequiredService<DefaultCryptoProvider>());
|
||||
services.AddSingleton<ICryptoProviderRegistry>(sp =>
|
||||
{
|
||||
var provider = sp.GetRequiredService<DefaultCryptoProvider>();
|
||||
return new CryptoProviderRegistry(new[] { provider });
|
||||
});
|
||||
|
||||
using var provider = services.BuildServiceProvider();
|
||||
using var provider = CreateCryptoProvider();
|
||||
await exporter.ExportAsync(provider, CancellationToken.None);
|
||||
|
||||
var exportId = exportedAt.ToString(optionsValue.DirectoryNameFormat, CultureInfo.InvariantCulture);
|
||||
@@ -449,7 +441,7 @@ public sealed class JsonFeedExporterTests : IDisposable
|
||||
return $"-----BEGIN {label}-----\n{base64}\n-----END {label}-----\n";
|
||||
}
|
||||
|
||||
private static byte[] BuildSigningInput(string protectedHeader, byte[] payload)
|
||||
private static byte[] BuildSigningInput(string protectedHeader, byte[] payload)
|
||||
{
|
||||
var headerBytes = Encoding.ASCII.GetBytes(protectedHeader);
|
||||
var buffer = new byte[headerBytes.Length + 1 + payload.Length];
|
||||
@@ -459,9 +451,9 @@ public sealed class JsonFeedExporterTests : IDisposable
|
||||
return buffer;
|
||||
}
|
||||
|
||||
private static byte[] Base64UrlDecode(string value)
|
||||
{
|
||||
var builder = new StringBuilder(value.Length + 3);
|
||||
private static byte[] Base64UrlDecode(string value)
|
||||
{
|
||||
var builder = new StringBuilder(value.Length + 3);
|
||||
foreach (var ch in value)
|
||||
{
|
||||
builder.Append(ch switch
|
||||
@@ -475,10 +467,19 @@ public sealed class JsonFeedExporterTests : IDisposable
|
||||
while (builder.Length % 4 != 0)
|
||||
{
|
||||
builder.Append('=');
|
||||
}
|
||||
|
||||
return Convert.FromBase64String(builder.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
return Convert.FromBase64String(builder.ToString());
|
||||
}
|
||||
|
||||
private static ServiceProvider CreateCryptoProvider()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddOptions();
|
||||
services.Configure<CryptoHashOptions>(_ => { });
|
||||
services.AddStellaOpsCrypto();
|
||||
return services.BuildServiceProvider();
|
||||
}
|
||||
|
||||
private sealed class StubAdvisoryStore : IAdvisoryStore
|
||||
{
|
||||
@@ -594,4 +595,4 @@ public sealed class JsonFeedExporterTests : IDisposable
|
||||
|
||||
public void Advance(TimeSpan delta) => _now = _now.Add(delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,5 +10,6 @@
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Exporter.Json/StellaOps.Concelier.Exporter.Json.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Models/StellaOps.Concelier.Models.csproj" />
|
||||
<ProjectReference Include="../../__Libraries/StellaOps.Concelier.Storage.Mongo/StellaOps.Concelier.Storage.Mongo.csproj" />
|
||||
<ProjectReference Include="../../../__Libraries/StellaOps.Cryptography.DependencyInjection/StellaOps.Cryptography.DependencyInjection.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user