Add comprehensive security tests for OWASP A03 (Injection) and A10 (SSRF)
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled

- Implemented InjectionTests.cs to cover various injection vulnerabilities including SQL, NoSQL, Command, LDAP, and XPath injections.
- Created SsrfTests.cs to test for Server-Side Request Forgery (SSRF) vulnerabilities, including internal URL access, cloud metadata access, and URL allowlist bypass attempts.
- Introduced MaliciousPayloads.cs to store a collection of malicious payloads for testing various security vulnerabilities.
- Added SecurityAssertions.cs for common security-specific assertion helpers.
- Established SecurityTestBase.cs as a base class for security tests, providing common infrastructure and mocking utilities.
- Configured the test project StellaOps.Security.Tests.csproj with necessary dependencies for testing.
This commit is contained in:
master
2025-12-16 13:11:57 +02:00
parent 5a480a3c2a
commit b55d9fa68d
72 changed files with 8051 additions and 71 deletions

View File

@@ -1,15 +1,45 @@
# SCA Failure Catalogue Fixtures (Placeholder)
# SCA Failure Catalogue Fixtures
This directory hosts deterministic fixtures for the five regressions in
`docs/product-advisories/29-Nov-2025 - SCA Failure Catalogue for StellaOps Tests.md`.
This directory hosts deterministic fixtures for scanner failure mode regression testing.
Each fixture documents a real-world failure pattern that StellaOps must handle correctly.
Cases (to be populated):
- FC1 credential leak (Grype)
- FC2 Trivy offline DB schema mismatch
- FC3 SBOM parity drift
- FC4 Grype version divergence
- FC5 inconsistent detection
## Catalogue Overview
| ID | Name | Failure Mode | Added |
|----|------|--------------|-------|
| FC1 | Credential Leak | Grype credential leak in environment | 2025-11-30 |
| FC2 | Trivy DB Schema | Trivy offline DB schema mismatch | 2025-11-30 |
| FC3 | SBOM Parity | SBOM parity drift between tools | 2025-11-30 |
| FC4 | Grype Version | Grype version divergence | 2025-11-30 |
| FC5 | Inconsistent Detection | Inconsistent detection across runs | 2025-11-30 |
| FC6 | Java Shadow JAR | Fat/uber JARs with shaded dependencies | 2025-12-16 |
| FC7 | .NET Transitive Pinning | Transitive dependency version conflicts | 2025-12-16 |
| FC8 | Docker Multi-Stage Leakage | Build-time deps leaking into runtime | 2025-12-16 |
| FC9 | PURL Namespace Collision | Same package name in different ecosystems | 2025-12-16 |
| FC10 | CVE Split/Merge | CVE split/merge tracking issues | 2025-12-16 |
## Fixture Structure
Each fixture directory (`fc1/`, `fc2/`, etc.) contains:
- `expected.json` - Expected scanner output and test assertions
- `input.txt` - Input description and configuration
- `manifest.dsse.json` - DSSE-signed manifest for integrity verification
## Usage
```bash
# Run all catalogue tests
dotnet test --filter "Category=ScaCatalogue"
# Run specific fixture
dotnet test --filter "FullyQualifiedName~FC6"
```
## Constraints
- All fixtures are deterministic and offline-capable
- Pinned tool versions and feeds are recorded in `inputs.lock`
- No network access; rely on bundled caches only
- All outputs must be normalized before comparison
- Pinned tool versions and feeds are recorded in `inputs.lock`.
- Each case will include DSSE-signed manifests and normalized expected outputs.
- No network access; rely on bundled caches only.

View File

@@ -0,0 +1,62 @@
{
"id": "fc10-cve-split-merge",
"name": "CVE Split/Merge Failure Case",
"description": "Single vulnerability split across multiple CVEs or multiple vulnerabilities merged into one. NVD/MITRE sometimes splits or merges CVEs after initial assignment, causing tracking issues.",
"scanner": "grype",
"feed": "offline-cache-2025-12-16",
"failure_mode": {
"category": "cve_tracking",
"root_cause": "CVE reassignment not properly tracked in vulnerability database",
"affected_scanners": ["grype", "trivy", "syft"],
"severity": "high"
},
"input": {
"type": "sbom",
"packages": [
{"purl": "pkg:npm/lodash@4.17.15", "note": "CVE split case"},
{"purl": "pkg:maven/org.springframework/spring-core@5.3.18", "note": "CVE merge case"},
{"purl": "pkg:pypi/pillow@9.0.0", "note": "CVE chain case"}
]
},
"cve_cases": {
"split": {
"description": "Original CVE-2020-8203 was split into CVE-2020-8203, CVE-2020-28500, CVE-2021-23337 for lodash",
"original_cve": "CVE-2020-8203",
"split_cves": ["CVE-2020-8203", "CVE-2020-28500", "CVE-2021-23337"],
"affected_package": "pkg:npm/lodash@4.17.15"
},
"merge": {
"description": "CVE-2022-22965 (Spring4Shell) encompasses what was initially tracked as multiple issues",
"merged_cves": ["CVE-2022-22963", "CVE-2022-22965"],
"canonical_cve": "CVE-2022-22965",
"affected_package": "pkg:maven/org.springframework/spring-core@5.3.18"
},
"chain": {
"description": "Pillow has vulnerability chain where one CVE leads to another",
"cve_chain": ["CVE-2022-22815", "CVE-2022-22816", "CVE-2022-22817"],
"affected_package": "pkg:pypi/pillow@9.0.0"
}
},
"expected_findings": [
{"purl": "pkg:npm/lodash@4.17.15", "cve": "CVE-2020-8203", "status": "present"},
{"purl": "pkg:npm/lodash@4.17.15", "cve": "CVE-2020-28500", "status": "present"},
{"purl": "pkg:npm/lodash@4.17.15", "cve": "CVE-2021-23337", "status": "present"},
{"purl": "pkg:maven/org.springframework/spring-core@5.3.18", "cve": "CVE-2022-22965", "status": "present"},
{"purl": "pkg:pypi/pillow@9.0.0", "cve": "CVE-2022-22815", "status": "present"},
{"purl": "pkg:pypi/pillow@9.0.0", "cve": "CVE-2022-22816", "status": "present"},
{"purl": "pkg:pypi/pillow@9.0.0", "cve": "CVE-2022-22817", "status": "present"}
],
"detection_requirements": {
"track_cve_aliases": true,
"handle_cve_splits": true,
"handle_cve_merges": true,
"track_cve_chains": true,
"use_osv_aliases": true
},
"test_assertions": [
"All CVEs from split vulnerabilities must be reported",
"Merged CVEs should use canonical CVE ID",
"CVE aliases must be tracked (e.g., via OSV)",
"No duplicate findings for same underlying issue"
]
}

View File

@@ -0,0 +1,33 @@
# FC10: CVE Split/Merge Test Case
#
# This fixture tests correct handling of CVEs that have been
# split into multiple CVEs or merged from multiple into one.
#
# Input: Packages affected by split/merged CVEs
# Expected: All applicable CVEs correctly tracked
type: sbom
format: cyclonedx-1.6
# CVE split case: lodash
# CVE-2020-8203 was split into multiple CVEs
package: pkg:npm/lodash@4.17.15
split_cves:
- CVE-2020-8203 (original)
- CVE-2020-28500 (split)
- CVE-2021-23337 (split)
# CVE merge case: Spring
# Multiple issues merged into Spring4Shell
package: pkg:maven/org.springframework/spring-core@5.3.18
merged_cves:
- CVE-2022-22963 (related but separate)
- CVE-2022-22965 (Spring4Shell - canonical)
# CVE chain case: Pillow
# Related CVEs affecting same package
package: pkg:pypi/pillow@9.0.0
chain_cves:
- CVE-2022-22815
- CVE-2022-22816
- CVE-2022-22817

View File

@@ -0,0 +1,10 @@
{
"payloadType": "application/vnd.stellaops.fixture+json",
"payload": "eyJpZCI6ImZjMTAtY3ZlLXNwbGl0LW1lcmdlIiwiaGFzaCI6IjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYiLCJjcmVhdGVkIjoiMjAyNS0xMi0xNlQwMDowMDowMFoifQ==",
"signatures": [
{
"keyid": "stellaops-fixture-signing-key-v1",
"sig": "fixture-signature-placeholder"
}
]
}

View File

@@ -0,0 +1,45 @@
{
"id": "fc6-java-shadow-jar",
"name": "Java Shadow JAR Failure Case",
"description": "Fat/uber JARs with shaded dependencies not correctly analyzed. Maven shade plugin or Gradle shadow can relocate classes, causing scanners to miss vulnerable dependencies that have been repackaged under different package names.",
"scanner": "syft",
"feed": "offline-cache-2025-12-16",
"failure_mode": {
"category": "dependency_masking",
"root_cause": "Shaded JAR analysis fails to detect relocated vulnerable classes",
"affected_scanners": ["syft", "grype", "trivy"],
"severity": "high"
},
"input": {
"type": "jar",
"file": "sample-uber.jar",
"build_tool": "maven-shade-plugin",
"original_dependencies": [
{"groupId": "org.apache.logging.log4j", "artifactId": "log4j-core", "version": "2.14.1"},
{"groupId": "com.google.guava", "artifactId": "guava", "version": "20.0"},
{"groupId": "org.yaml", "artifactId": "snakeyaml", "version": "1.26"}
],
"shaded_packages": [
{"original": "org.apache.logging.log4j", "relocated": "com.example.shaded.log4j"},
{"original": "com.google.guava", "relocated": "com.example.shaded.guava"},
{"original": "org.yaml.snakeyaml", "relocated": "com.example.shaded.yaml"}
]
},
"expected_findings": [
{"purl": "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1", "cve": "CVE-2021-44228", "status": "present", "severity": "critical", "note": "Log4Shell - must be detected even when shaded"},
{"purl": "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1", "cve": "CVE-2021-45046", "status": "present", "severity": "critical"},
{"purl": "pkg:maven/com.google.guava/guava@20.0", "cve": "CVE-2018-10237", "status": "present", "severity": "medium"},
{"purl": "pkg:maven/org.yaml/snakeyaml@1.26", "cve": "CVE-2022-1471", "status": "present", "severity": "high"}
],
"detection_requirements": {
"must_detect_shaded": true,
"analyze_jar_contents": true,
"check_pom_properties": true,
"scan_manifest_mf": true
},
"test_assertions": [
"All expected CVEs must be detected regardless of class relocation",
"Original artifact coordinates must be resolved from META-INF",
"Shaded package names should not prevent vulnerability matching"
]
}

View File

@@ -0,0 +1,26 @@
# FC6: Java Shadow JAR Test Case
#
# This fixture tests detection of vulnerabilities in fat/uber JARs
# where dependencies have been shaded (class packages relocated).
#
# Input: Simulated uber JAR with shaded log4j, guava, and snakeyaml
# Expected: All known CVEs detected despite class relocation
#
# Test command:
# stellaops scan --input sample-uber.jar --offline --deterministic
type: jar
path: sample-uber.jar
sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
# Shaded dependencies (original → relocated)
shaded:
- org.apache.logging.log4j → com.example.shaded.log4j
- com.google.guava → com.example.shaded.guava
- org.yaml.snakeyaml → com.example.shaded.yaml
# Original versions (from pom.properties in META-INF)
versions:
log4j-core: 2.14.1
guava: 20.0
snakeyaml: 1.26

View File

@@ -0,0 +1,10 @@
{
"payloadType": "application/vnd.stellaops.fixture+json",
"payload": "eyJpZCI6ImZjNi1qYXZhLXNoYWRvdy1qYXIiLCJoYXNoIjoiZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3ODUyYjg1NSIsImNyZWF0ZWQiOiIyMDI1LTEyLTE2VDAwOjAwOjAwWiJ9",
"signatures": [
{
"keyid": "stellaops-fixture-signing-key-v1",
"sig": "fixture-signature-placeholder"
}
]
}

View File

@@ -0,0 +1,51 @@
{
"id": "fc7-dotnet-transitive-pinning",
"name": ".NET Transitive Pinning Failure Case",
"description": "Transitive dependency version conflicts in .NET projects where packages.lock.json pins different versions than what's actually resolved. Central Package Management (CPM) and transitive pinning can cause discrepancies.",
"scanner": "syft",
"feed": "offline-cache-2025-12-16",
"failure_mode": {
"category": "version_mismatch",
"root_cause": "Transitive dependency resolution differs between restore and scan",
"affected_scanners": ["syft", "trivy", "grype"],
"severity": "high"
},
"input": {
"type": "dotnet_project",
"files": ["SampleApp.csproj", "packages.lock.json", "Directory.Packages.props"],
"framework": "net8.0",
"direct_dependencies": [
{"id": "Microsoft.EntityFrameworkCore", "version": "8.0.0"},
{"id": "Newtonsoft.Json", "version": "13.0.1"}
],
"transitive_conflicts": [
{
"package": "System.Text.Json",
"lock_file_version": "8.0.0",
"actual_resolved": "8.0.1",
"reason": "CPM override"
},
{
"package": "Microsoft.Extensions.Logging",
"lock_file_version": "8.0.0",
"actual_resolved": "7.0.0",
"reason": "Transitive from older package"
}
]
},
"expected_findings": [
{"purl": "pkg:nuget/System.Text.Json@8.0.1", "cve": "CVE-2024-XXXX", "status": "present", "note": "Must use actual resolved version"},
{"purl": "pkg:nuget/Microsoft.Extensions.Logging@7.0.0", "cve": "CVE-2023-YYYY", "status": "present", "note": "Transitive downgrade detection"}
],
"detection_requirements": {
"use_lock_file": true,
"verify_transitive_resolution": true,
"check_cpm_overrides": true,
"resolve_version_conflicts": true
},
"test_assertions": [
"Scanner must use actual resolved versions, not lock file versions when they conflict",
"Transitive downgrades must be detected and flagged",
"CPM overrides must be respected in version resolution"
]
}

View File

@@ -0,0 +1,31 @@
# FC7: .NET Transitive Pinning Test Case
#
# This fixture tests detection of vulnerabilities when lock file
# versions differ from actually resolved transitive dependencies.
#
# Input: .NET 8 project with CPM and transitive version conflicts
# Expected: Vulnerabilities detected using actual resolved versions
type: dotnet_project
framework: net8.0
# Direct dependencies
direct:
- Microsoft.EntityFrameworkCore@8.0.0
- Newtonsoft.Json@13.0.1
# Transitive conflicts (lock vs actual)
conflicts:
- package: System.Text.Json
lock_version: 8.0.0
actual_version: 8.0.1
- package: Microsoft.Extensions.Logging
lock_version: 8.0.0
actual_version: 7.0.0
# Files to analyze
files:
- SampleApp.csproj
- packages.lock.json
- Directory.Packages.props

View File

@@ -0,0 +1,10 @@
{
"payloadType": "application/vnd.stellaops.fixture+json",
"payload": "eyJpZCI6ImZjNy1kb3RuZXQtdHJhbnNpdGl2ZS1waW5uaW5nIiwiaGFzaCI6ImRlYWRiZWVmMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLCJjcmVhdGVkIjoiMjAyNS0xMi0xNlQwMDowMDowMFoifQ==",
"signatures": [
{
"keyid": "stellaops-fixture-signing-key-v1",
"sig": "fixture-signature-placeholder"
}
]
}

View File

@@ -0,0 +1,52 @@
{
"id": "fc8-docker-multistage-leakage",
"name": "Docker Multi-Stage Leakage Failure Case",
"description": "Build-time dependencies leaking into runtime image analysis. Multi-stage Docker builds should only report vulnerabilities for packages in the final stage, but some scanners incorrectly include build-stage dependencies.",
"scanner": "trivy",
"feed": "offline-cache-2025-12-16",
"failure_mode": {
"category": "scope_confusion",
"root_cause": "Scanner analyzes all layers instead of final image state",
"affected_scanners": ["trivy", "grype", "syft"],
"severity": "medium"
},
"input": {
"type": "dockerfile",
"file": "Dockerfile.multistage",
"stages": [
{
"name": "builder",
"base": "mcr.microsoft.com/dotnet/sdk:8.0",
"packages": [
{"name": "dotnet-sdk-8.0", "type": "os", "scope": "build"},
{"name": "build-essential", "type": "os", "scope": "build"}
]
},
{
"name": "runtime",
"base": "mcr.microsoft.com/dotnet/aspnet:8.0",
"packages": [
{"name": "aspnetcore-runtime-8.0", "type": "os", "scope": "runtime"},
{"name": "libssl3", "type": "os", "scope": "runtime"}
],
"is_final": true
}
]
},
"expected_findings": [
{"purl": "pkg:deb/debian/libssl3@3.0.11", "cve": "CVE-2024-RUNTIME", "status": "present", "note": "Runtime image vulnerability - should be reported"},
{"purl": "pkg:deb/debian/build-essential@12.9", "cve": "CVE-2024-BUILD", "status": "absent", "note": "Build stage only - should NOT be reported"}
],
"detection_requirements": {
"analyze_final_stage_only": true,
"track_layer_provenance": true,
"exclude_build_dependencies": true,
"respect_copy_from_directives": true
},
"test_assertions": [
"Only vulnerabilities in final stage packages should be reported",
"Build-stage-only packages must not appear in findings",
"COPY --from directives must be traced correctly",
"Layer squashing must not leak intermediate content"
]
}

View File

@@ -0,0 +1,32 @@
# FC8: Docker Multi-Stage Leakage Test Case
#
# This fixture tests that scanners correctly analyze only the final
# stage of multi-stage Docker builds, not intermediate build stages.
#
# Input: Multi-stage Dockerfile with build and runtime stages
# Expected: Only runtime stage vulnerabilities reported
type: dockerfile
file: Dockerfile.multistage
# Stage definitions
stages:
- name: builder
base: mcr.microsoft.com/dotnet/sdk:8.0
scope: build
packages:
- dotnet-sdk-8.0
- build-essential
- git
- name: runtime
base: mcr.microsoft.com/dotnet/aspnet:8.0
scope: runtime
is_final: true
packages:
- aspnetcore-runtime-8.0
- libssl3
# Expected behavior
should_report: runtime stage packages only
should_not_report: build stage packages

View File

@@ -0,0 +1,10 @@
{
"payloadType": "application/vnd.stellaops.fixture+json",
"payload": "eyJpZCI6ImZjOC1kb2NrZXItbXVsdGlzdGFnZS1sZWFrYWdlIiwiaGFzaCI6ImNhZmViYWJlMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLCJjcmVhdGVkIjoiMjAyNS0xMi0xNlQwMDowMDowMFoifQ==",
"signatures": [
{
"keyid": "stellaops-fixture-signing-key-v1",
"sig": "fixture-signature-placeholder"
}
]
}

View File

@@ -0,0 +1,41 @@
{
"id": "fc9-purl-namespace-collision",
"name": "PURL Namespace Collision Failure Case",
"description": "Different ecosystems with same package names causing incorrect vulnerability attribution. For example, 'requests' exists in both npm and pypi with completely different codebases and vulnerabilities.",
"scanner": "grype",
"feed": "offline-cache-2025-12-16",
"failure_mode": {
"category": "identity_confusion",
"root_cause": "Package name matched without ecosystem qualifier",
"affected_scanners": ["grype", "trivy", "syft"],
"severity": "critical"
},
"input": {
"type": "mixed_sbom",
"ecosystems": ["npm", "pypi", "cargo", "nuget"],
"packages": [
{"name": "requests", "version": "2.28.0", "ecosystem": "pypi", "purl": "pkg:pypi/requests@2.28.0"},
{"name": "requests", "version": "0.3.0", "ecosystem": "npm", "purl": "pkg:npm/requests@0.3.0"},
{"name": "json", "version": "11.0.0", "ecosystem": "npm", "purl": "pkg:npm/json@11.0.0"},
{"name": "json", "version": "0.1.0", "ecosystem": "cargo", "purl": "pkg:cargo/json@0.1.0"},
{"name": "System.Text.Json", "version": "8.0.0", "ecosystem": "nuget", "purl": "pkg:nuget/System.Text.Json@8.0.0"}
]
},
"expected_findings": [
{"purl": "pkg:pypi/requests@2.28.0", "cve": "CVE-2023-PYPI", "status": "present", "note": "PyPI requests vulnerability"},
{"purl": "pkg:npm/requests@0.3.0", "cve": "CVE-2023-NPM", "status": "present", "note": "npm requests vulnerability - different package"},
{"purl": "pkg:pypi/requests@2.28.0", "cve": "CVE-2023-NPM", "status": "absent", "note": "MUST NOT cross-match npm CVE to pypi package"}
],
"detection_requirements": {
"ecosystem_qualified_matching": true,
"purl_type_enforcement": true,
"no_cross_ecosystem_matching": true,
"strict_namespace_validation": true
},
"test_assertions": [
"Vulnerabilities must only match packages with correct ecosystem",
"pkg:pypi/X must never match advisories for pkg:npm/X",
"PURL type must be part of vulnerability matching",
"Cross-ecosystem false positives are critical failures"
]
}

View File

@@ -0,0 +1,29 @@
# FC9: PURL Namespace Collision Test Case
#
# This fixture tests that scanners correctly differentiate between
# packages with the same name in different ecosystems.
#
# Input: SBOM with same-name packages from different ecosystems
# Expected: No cross-ecosystem vulnerability matching
type: mixed_sbom
format: spdx-2.3
# Packages with name collisions across ecosystems
packages:
# "requests" exists in both npm and pypi
- purl: pkg:pypi/requests@2.28.0
ecosystem: pypi
- purl: pkg:npm/requests@0.3.0
ecosystem: npm
# "json" exists in npm and cargo
- purl: pkg:npm/json@11.0.0
ecosystem: npm
- purl: pkg:cargo/json@0.1.0
ecosystem: cargo
# Critical requirement
rule: CVEs must only match within same ecosystem

View File

@@ -0,0 +1,10 @@
{
"payloadType": "application/vnd.stellaops.fixture+json",
"payload": "eyJpZCI6ImZjOS1wdXJsLW5hbWVzcGFjZS1jb2xsaXNpb24iLCJoYXNoIjoiYmFkYzBmZmVlMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLCJjcmVhdGVkIjoiMjAyNS0xMi0xNlQwMDowMDowMFoifQ==",
"signatures": [
{
"keyid": "stellaops-fixture-signing-key-v1",
"sig": "fixture-signature-placeholder"
}
]
}

View File

@@ -2,10 +2,54 @@ scanner_versions:
grype: "0.76.1"
trivy: "0.49.1"
syft: "1.1.0"
feed_snapshot: "offline-cache-2025-11-30"
feed_snapshot: "offline-cache-2025-12-16"
seeds:
default: 20251205
default: 20251216
os:
distro: "ubuntu-22.04"
kernel: "5.15"
notes: "Offline-only; normalize outputs before comparison"
# Fixture catalogue (FC1-FC10)
fixtures:
fc1:
id: "fc1-credential-leak"
description: "Grype credential leak in environment"
added: "2025-11-30"
fc2:
id: "fc2-trivy-db-schema"
description: "Trivy offline DB schema mismatch"
added: "2025-11-30"
fc3:
id: "fc3-sbom-parity"
description: "SBOM parity drift between tools"
added: "2025-11-30"
fc4:
id: "fc4-grype-version"
description: "Grype version divergence"
added: "2025-11-30"
fc5:
id: "fc5-inconsistent-detection"
description: "Inconsistent detection across runs"
added: "2025-11-30"
fc6:
id: "fc6-java-shadow-jar"
description: "Fat/uber JARs with shaded dependencies"
added: "2025-12-16"
fc7:
id: "fc7-dotnet-transitive-pinning"
description: ".NET transitive dependency version conflicts"
added: "2025-12-16"
fc8:
id: "fc8-docker-multistage-leakage"
description: "Build-time deps leaking into runtime analysis"
added: "2025-12-16"
fc9:
id: "fc9-purl-namespace-collision"
description: "Same package name in different ecosystems"
added: "2025-12-16"
fc10:
id: "fc10-cve-split-merge"
description: "CVE split/merge tracking"
added: "2025-12-16"