190 lines
5.9 KiB
C#
190 lines
5.9 KiB
C#
using System.Reflection;
|
|
|
|
namespace StellaOps.BinaryIndex.GroundTruth.SecDb.Tests.Fixtures;
|
|
|
|
/// <summary>
|
|
/// Provides access to deterministic test fixtures for offline testing.
|
|
/// </summary>
|
|
public static class FixtureProvider
|
|
{
|
|
private static readonly string FixturesPath;
|
|
|
|
static FixtureProvider()
|
|
{
|
|
var assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;
|
|
FixturesPath = Path.Combine(assemblyDir, "Fixtures");
|
|
|
|
// Also try the source directory for development
|
|
if (!Directory.Exists(FixturesPath))
|
|
{
|
|
var sourceDir = FindSourceFixturesDirectory();
|
|
if (sourceDir is not null)
|
|
{
|
|
FixturesPath = sourceDir;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get sample SecDB YAML content for main repository.
|
|
/// </summary>
|
|
public static string GetSampleSecDbMain()
|
|
{
|
|
var path = Path.Combine(FixturesPath, "main.yaml");
|
|
if (!File.Exists(path))
|
|
{
|
|
// Return inline fixture if file doesn't exist
|
|
return SampleSecDbMainContent;
|
|
}
|
|
return File.ReadAllText(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get sample SecDB YAML content for community repository.
|
|
/// </summary>
|
|
public static string GetSampleSecDbCommunity()
|
|
{
|
|
var path = Path.Combine(FixturesPath, "community.yaml");
|
|
if (!File.Exists(path))
|
|
{
|
|
return SampleSecDbCommunityContent;
|
|
}
|
|
return File.ReadAllText(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a fixture file as a stream.
|
|
/// </summary>
|
|
public static Stream GetFixtureStream(string name)
|
|
{
|
|
var path = Path.Combine(FixturesPath, name);
|
|
if (!File.Exists(path))
|
|
{
|
|
throw new FileNotFoundException($"Fixture not found: {path}");
|
|
}
|
|
return File.OpenRead(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if a fixture exists.
|
|
/// </summary>
|
|
public static bool FixtureExists(string name)
|
|
{
|
|
var path = Path.Combine(FixturesPath, name);
|
|
return File.Exists(path);
|
|
}
|
|
|
|
private static string? FindSourceFixturesDirectory()
|
|
{
|
|
var dir = Directory.GetCurrentDirectory();
|
|
while (dir is not null)
|
|
{
|
|
var candidate = Path.Combine(dir, "src", "BinaryIndex", "__Tests",
|
|
"StellaOps.BinaryIndex.GroundTruth.SecDb.Tests", "Fixtures");
|
|
if (Directory.Exists(candidate))
|
|
{
|
|
return candidate;
|
|
}
|
|
dir = Directory.GetParent(dir)?.FullName;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Inline sample SecDB main.yaml content for deterministic testing.
|
|
/// Based on Alpine SecDB format.
|
|
/// </summary>
|
|
private const string SampleSecDbMainContent = """
|
|
distroversion: v3.19
|
|
reponame: main
|
|
urlprefix: https://dl-cdn.alpinelinux.org/alpine/v3.19/main
|
|
packages:
|
|
- pkg: curl
|
|
secfixes:
|
|
8.5.0-r0:
|
|
- CVE-2023-46218 Improper validation of HTTP headers
|
|
- CVE-2023-46219 Double free in async URL resolver
|
|
8.4.0-r0:
|
|
- CVE-2023-38545 SOCKS5 heap buffer overflow
|
|
8.1.2-r0:
|
|
- CVE-2023-27535 FTP injection vulnerability
|
|
- pkg: openssl
|
|
secfixes:
|
|
3.1.4-r3:
|
|
- CVE-2024-0727 PKCS12 decoding crash
|
|
3.1.4-r0:
|
|
- CVE-2023-5678 Denial of service
|
|
3.1.2-r0:
|
|
- CVE-2023-3817 Excessive time checking DH parameters
|
|
- pkg: linux-lts
|
|
secfixes:
|
|
6.1.67-r0:
|
|
- CVE-2023-6817 Use-after-free in netfilter
|
|
- CVE-2023-6606 Out-of-bounds read in SMB
|
|
6.1.64-r0:
|
|
- CVE-2023-5717 User-mode root exploit via perf
|
|
""";
|
|
|
|
/// <summary>
|
|
/// Inline sample SecDB community.yaml content.
|
|
/// </summary>
|
|
private const string SampleSecDbCommunityContent = """
|
|
distroversion: v3.19
|
|
reponame: community
|
|
urlprefix: https://dl-cdn.alpinelinux.org/alpine/v3.19/community
|
|
packages:
|
|
- pkg: go
|
|
secfixes:
|
|
1.21.5-r0:
|
|
- CVE-2023-45283 Path traversal on Windows
|
|
- CVE-2023-45284 Runtime panic in crypto/tls
|
|
1.21.4-r0:
|
|
- CVE-2023-44487 HTTP/2 rapid reset attack
|
|
- pkg: nodejs
|
|
secfixes:
|
|
20.10.0-r0:
|
|
- CVE-2023-46809 Permissions policy bypass
|
|
20.9.0-r0:
|
|
- CVE-2023-38552 Integrity bypass via TLS/HTTPS
|
|
- pkg: chromium
|
|
secfixes:
|
|
120.0.6099.71-r0:
|
|
- CVE-2023-6702 Type confusion in V8
|
|
119.0.6045.199-r0:
|
|
- CVE-2023-6345 Integer overflow in Skia
|
|
- pkg: unfixed-example
|
|
secfixes:
|
|
"0":
|
|
- CVE-2023-99999 Example unfixed vulnerability
|
|
""";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Test fixture constants for SecDB tests.
|
|
/// </summary>
|
|
public static class FixtureConstants
|
|
{
|
|
// Sample package info
|
|
public const string SamplePackageCurl = "curl";
|
|
public const string SamplePackageOpenssl = "openssl";
|
|
public const string SamplePackageGo = "go";
|
|
public const string SamplePackageNodejs = "nodejs";
|
|
|
|
// Sample branches
|
|
public const string SampleBranchV319 = "v3.19";
|
|
public const string SampleBranchEdge = "edge";
|
|
|
|
// Sample repositories
|
|
public const string SampleRepoMain = "main";
|
|
public const string SampleRepoCommunity = "community";
|
|
|
|
// Expected CVE counts
|
|
public const int ExpectedCurlCveCount = 4;
|
|
public const int ExpectedOpensslCveCount = 3;
|
|
|
|
// Sample CVEs
|
|
public const string SampleCveCurl = "CVE-2023-46218";
|
|
public const string SampleCveOpenssl = "CVE-2024-0727";
|
|
public const string SampleCveUnfixed = "CVE-2023-99999";
|
|
}
|