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

- 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:
master
2025-11-08 20:53:45 +02:00
parent 515975edc5
commit 536f6249a6
837 changed files with 37279 additions and 14675 deletions

View File

@@ -0,0 +1,136 @@
using System;
using Microsoft.Extensions.Options;
using StellaOps.Policy;
using StellaOps.Policy.Engine.Compilation;
using StellaOps.Policy.Engine.Options;
using StellaOps.Policy.Engine.Services;
using Xunit;
namespace StellaOps.Policy.Engine.Tests;
public sealed class PolicyCompilationServiceTests
{
private const string SimplePolicy = """
policy "Sample" syntax "stella-dsl@1" {
rule block_high priority 10 {
when severity.normalized >= "High"
then status := "blocked"
because "Block high severity findings"
}
rule warn_medium priority 20 {
when severity.normalized >= "Medium"
then status := "warn"
because "Warn on medium severity findings"
}
}
""";
[Fact]
public void Compile_ReturnsComplexityReport_WhenWithinLimits()
{
var service = CreateService(maxComplexityScore: 1000, maxDurationMilliseconds: 1000, simulatedDurationMilliseconds: 12.3);
var request = new PolicyCompileRequest(new PolicyDslPayload("stella-dsl@1", SimplePolicy));
var result = service.Compile(request);
Assert.True(result.Success);
Assert.NotNull(result.Digest);
Assert.NotNull(result.Complexity);
Assert.True(result.Complexity!.Score > 0);
Assert.True(result.Complexity.RuleCount >= 2);
Assert.Equal(13, result.DurationMilliseconds);
Assert.True(result.Diagnostics.IsDefaultOrEmpty);
}
[Fact]
public void Compile_Fails_WhenComplexityExceedsThreshold()
{
var service = CreateService(maxComplexityScore: 1, maxDurationMilliseconds: 1000, simulatedDurationMilliseconds: 2);
var request = new PolicyCompileRequest(new PolicyDslPayload("stella-dsl@1", SimplePolicy));
var result = service.Compile(request);
Assert.False(result.Success);
Assert.NotNull(result.Complexity);
Assert.Equal(2, result.DurationMilliseconds);
var diagnostic = Assert.Single(result.Diagnostics);
Assert.Equal(PolicyEngineDiagnosticCodes.CompilationComplexityExceeded, diagnostic.Code);
Assert.Equal(PolicyIssueSeverity.Error, diagnostic.Severity);
}
[Fact]
public void Compile_Fails_WhenDurationExceedsThreshold()
{
var service = CreateService(maxComplexityScore: 1000, maxDurationMilliseconds: 1, simulatedDurationMilliseconds: 5.2);
var request = new PolicyCompileRequest(new PolicyDslPayload("stella-dsl@1", SimplePolicy));
var result = service.Compile(request);
Assert.False(result.Success);
Assert.NotNull(result.Complexity);
Assert.Equal(6, result.DurationMilliseconds);
var diagnostic = Assert.Single(result.Diagnostics);
Assert.Equal(PolicyEngineDiagnosticCodes.CompilationComplexityExceeded, diagnostic.Code);
}
private static PolicyCompilationService CreateService(double maxComplexityScore, int maxDurationMilliseconds, double simulatedDurationMilliseconds)
{
var compiler = new PolicyCompiler();
var analyzer = new PolicyComplexityAnalyzer();
var options = new PolicyEngineOptions();
options.Compilation.MaxComplexityScore = maxComplexityScore;
options.Compilation.MaxDurationMilliseconds = maxDurationMilliseconds;
var optionsMonitor = new StaticOptionsMonitor<PolicyEngineOptions>(options);
var timeProvider = new FakeTimeProvider(simulatedDurationMilliseconds);
return new PolicyCompilationService(compiler, analyzer, optionsMonitor, timeProvider);
}
private sealed class StaticOptionsMonitor<T> : IOptionsMonitor<T>
where T : class
{
public StaticOptionsMonitor(T value)
{
CurrentValue = value ?? throw new ArgumentNullException(nameof(value));
}
public T CurrentValue { get; }
public T Get(string? name) => CurrentValue;
public IDisposable OnChange(Action<T, string> listener) => Disposable.Instance;
private sealed class Disposable : IDisposable
{
public static readonly Disposable Instance = new();
public void Dispose()
{
}
}
}
private sealed class FakeTimeProvider : TimeProvider
{
private readonly long elapsedCounts;
private readonly long frequency = 1_000_000;
private bool firstCall = true;
public FakeTimeProvider(double milliseconds)
{
elapsedCounts = (long)Math.Round(milliseconds * frequency / 1000d);
}
public override long GetTimestamp()
{
if (firstCall)
{
firstCall = false;
return 0;
}
return elapsedCounts;
}
public override long TimestampFrequency => frequency;
}
}