consolidate the tests locations
This commit is contained in:
24
tests/fixtures/invalid/README.md
vendored
24
tests/fixtures/invalid/README.md
vendored
@@ -1,24 +0,0 @@
|
||||
# Invalid Fixtures for Negative Testing
|
||||
|
||||
This directory contains intentionally invalid SBOM fixtures used for CI negative testing.
|
||||
These fixtures MUST fail schema validation to ensure the CI pipeline correctly detects errors.
|
||||
|
||||
## CycloneDX Invalid Fixtures
|
||||
|
||||
| File | Defect | Expected Error |
|
||||
|------|--------|----------------|
|
||||
| `cyclonedx-wrong-version.json` | specVersion "2.0" doesn't exist | Invalid enum value for specVersion |
|
||||
| `cyclonedx-missing-required.json` | Missing required specVersion field | Missing required property: specVersion |
|
||||
| `cyclonedx-invalid-component.json` | Component missing name and type | Required properties missing in component |
|
||||
|
||||
## CI Usage
|
||||
|
||||
The schema validation workflow uses the `tests/fixtures/invalid/` directory for negative test cases.
|
||||
When `--expect-failures` is passed, the CI expects these files to fail validation.
|
||||
|
||||
## Adding New Test Cases
|
||||
|
||||
1. Create a new JSON file with an intentional schema violation
|
||||
2. Add a `$comment` field explaining the defect
|
||||
3. Update this README with the expected error
|
||||
4. Ensure the file has the correct format marker (e.g., `"bomFormat": "CycloneDX"`)
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"$comment": "INTENTIONALLY INVALID CycloneDX fixture - component missing required 'name' and 'type' fields.",
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.6",
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"timestamp": "2025-12-25T00:00:00Z"
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"invalid-field": "this-is-not-valid",
|
||||
"purl": "pkg:npm/missing-required-fields@1.0.0"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"$comment": "INTENTIONALLY INVALID CycloneDX fixture - missing required 'specVersion' field.",
|
||||
"bomFormat": "CycloneDX",
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"timestamp": "2025-12-25T00:00:00Z"
|
||||
},
|
||||
"components": []
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"$comment": "INTENTIONALLY INVALID CycloneDX fixture for negative testing.",
|
||||
"$comment2": "specVersion 2.0 does not exist and should fail schema validation.",
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "2.0",
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"timestamp": "2025-12-25T00:00:00Z"
|
||||
},
|
||||
"components": []
|
||||
}
|
||||
89
tests/fixtures/micro/micro-fixtures.ts
vendored
89
tests/fixtures/micro/micro-fixtures.ts
vendored
@@ -1,89 +0,0 @@
|
||||
/**
|
||||
* Micro-interaction test fixtures with deterministic seeds (MI8)
|
||||
*
|
||||
* Usage:
|
||||
* - Import these constants in Storybook stories and Playwright tests
|
||||
* - Use frozenTimestamp for all date operations
|
||||
* - Use rngSeed for any randomized content
|
||||
*/
|
||||
|
||||
// Frozen timestamp: 2025-12-04T12:00:00Z (as per advisory)
|
||||
export const FROZEN_TIMESTAMP = new Date('2025-12-04T12:00:00.000Z');
|
||||
export const FROZEN_TIMESTAMP_MS = 1733313600000;
|
||||
|
||||
// Fixed RNG seed as per advisory: 0x5EED2025
|
||||
export const RNG_SEED = 0x5EED2025;
|
||||
|
||||
// Deterministic UUID generator (seeded)
|
||||
export function seededUuid(seed: number = RNG_SEED, index: number = 0): string {
|
||||
const hash = ((seed + index) * 2654435761) >>> 0;
|
||||
const hex = hash.toString(16).padStart(8, '0');
|
||||
return `${hex.slice(0, 8)}-${hex.slice(0, 4)}-4${hex.slice(1, 4)}-8${hex.slice(4, 7)}-${hex}0000`.slice(0, 36);
|
||||
}
|
||||
|
||||
// Skeleton state fixture
|
||||
export const skeletonFixture = {
|
||||
showAfterMs: 400,
|
||||
loadingDurationMs: 1200,
|
||||
state: 'loading' as const,
|
||||
timestamp: FROZEN_TIMESTAMP,
|
||||
};
|
||||
|
||||
// Error state fixture
|
||||
export const errorFixture = {
|
||||
code: 'UI_ERR_001',
|
||||
message: 'Failed to load data',
|
||||
retryAvailable: true,
|
||||
timestamp: FROZEN_TIMESTAMP,
|
||||
correlationId: seededUuid(RNG_SEED, 1),
|
||||
};
|
||||
|
||||
// Offline state fixture
|
||||
export const offlineFixture = {
|
||||
isOffline: true,
|
||||
lastOnline: new Date(FROZEN_TIMESTAMP_MS - 300000), // 5 minutes ago
|
||||
cachedDataAge: 'less than 1 hour',
|
||||
timestamp: FROZEN_TIMESTAMP,
|
||||
};
|
||||
|
||||
// Toast/snackbar fixture
|
||||
export const toastFixture = {
|
||||
id: seededUuid(RNG_SEED, 2),
|
||||
type: 'info' as const,
|
||||
message: 'Changes saved successfully',
|
||||
undoAvailable: true,
|
||||
undoWindowMs: 8000,
|
||||
timestamp: FROZEN_TIMESTAMP,
|
||||
};
|
||||
|
||||
// Reduced motion test config
|
||||
export const reducedMotionConfig = {
|
||||
enabled: true,
|
||||
emulateQuery: true,
|
||||
dataAttribute: 'data-reduce-motion',
|
||||
dataValue: '1',
|
||||
};
|
||||
|
||||
// Playwright/Storybook timer config
|
||||
export const timerConfig = {
|
||||
useFakeTimers: true,
|
||||
now: FROZEN_TIMESTAMP_MS,
|
||||
shouldAdvanceTime: false,
|
||||
};
|
||||
|
||||
// Sample telemetry event
|
||||
export const sampleTelemetryEvent = {
|
||||
schema_version: 'v1.0',
|
||||
event_type: 'ui.micro.interaction',
|
||||
timestamp: FROZEN_TIMESTAMP.toISOString(),
|
||||
tenant_id: 'test-tenant',
|
||||
surface: 'dashboard',
|
||||
component: 'button',
|
||||
action: 'click',
|
||||
latency_ms: 45,
|
||||
outcome: 'success',
|
||||
reduced_motion: false,
|
||||
offline_mode: false,
|
||||
error_code: null,
|
||||
correlation_id: seededUuid(RNG_SEED, 3),
|
||||
};
|
||||
75
tests/fixtures/offline-bundle/README.md
vendored
75
tests/fixtures/offline-bundle/README.md
vendored
@@ -1,75 +0,0 @@
|
||||
# Offline Bundle Test Fixtures
|
||||
|
||||
This directory contains test fixtures for offline/air-gap testing.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
offline-bundle/
|
||||
├── manifest.json # Bundle manifest
|
||||
├── feeds/ # Vulnerability feed snapshots
|
||||
│ ├── nvd-snapshot.json
|
||||
│ ├── ghsa-snapshot.json
|
||||
│ └── distro/
|
||||
│ ├── alpine.json
|
||||
│ ├── debian.json
|
||||
│ └── rhel.json
|
||||
├── policies/ # OPA/Rego policies
|
||||
│ ├── default.rego
|
||||
│ └── strict.rego
|
||||
├── keys/ # Test signing keys
|
||||
│ ├── signing-key.pem
|
||||
│ └── signing-key.pub
|
||||
├── certs/ # Test certificates
|
||||
│ ├── trust-root.pem
|
||||
│ └── intermediate.pem
|
||||
├── vex/ # Sample VEX documents
|
||||
│ └── vendor-vex.json
|
||||
└── images/ # Test container image tarballs
|
||||
├── test-image.tar
|
||||
├── vuln-image.tar
|
||||
└── vuln-with-vex.tar
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Set the `STELLAOPS_OFFLINE_BUNDLE` environment variable to point to this directory:
|
||||
|
||||
```bash
|
||||
export STELLAOPS_OFFLINE_BUNDLE=/path/to/tests/fixtures/offline-bundle
|
||||
```
|
||||
|
||||
Tests that extend `NetworkIsolatedTestBase` will automatically use this bundle.
|
||||
|
||||
## Generating Test Images
|
||||
|
||||
To create test image tarballs:
|
||||
|
||||
```bash
|
||||
# Pull and save test images
|
||||
docker pull alpine:3.18
|
||||
docker save alpine:3.18 -o images/test-image.tar
|
||||
|
||||
# For vulnerable images
|
||||
docker pull vulnerables/web-dvwa:latest
|
||||
docker save vulnerables/web-dvwa:latest -o images/vuln-image.tar
|
||||
```
|
||||
|
||||
## Feed Snapshots
|
||||
|
||||
Feed snapshots should be representative samples from real feeds, sufficient for testing but small enough to commit to the repo.
|
||||
|
||||
## Test Keys
|
||||
|
||||
⚠️ **WARNING:** Keys in this directory are for **testing only**. Never use these in production.
|
||||
|
||||
To generate test keys:
|
||||
|
||||
```bash
|
||||
# Generate test signing key
|
||||
openssl genrsa -out keys/signing-key.pem 2048
|
||||
openssl rsa -in keys/signing-key.pem -pubout -out keys/signing-key.pub
|
||||
|
||||
# Generate test CA
|
||||
openssl req -new -x509 -key keys/signing-key.pem -out certs/trust-root.pem -days 3650
|
||||
```
|
||||
38
tests/fixtures/offline-bundle/manifest.json
vendored
38
tests/fixtures/offline-bundle/manifest.json
vendored
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"bundleId": "test-offline-bundle-v1",
|
||||
"schemaVersion": "1.0.0",
|
||||
"createdAt": "2025-12-22T00:00:00Z",
|
||||
"description": "Test offline bundle for air-gap testing",
|
||||
"contents": {
|
||||
"feeds": [
|
||||
"feeds/nvd-snapshot.json",
|
||||
"feeds/ghsa-snapshot.json",
|
||||
"feeds/distro/alpine.json",
|
||||
"feeds/distro/debian.json"
|
||||
],
|
||||
"policies": [
|
||||
"policies/default.rego",
|
||||
"policies/strict.rego"
|
||||
],
|
||||
"keys": [
|
||||
"keys/signing-key.pem",
|
||||
"keys/signing-key.pub"
|
||||
],
|
||||
"certs": [
|
||||
"certs/trust-root.pem",
|
||||
"certs/intermediate.pem"
|
||||
],
|
||||
"vex": [
|
||||
"vex/vendor-vex.json"
|
||||
],
|
||||
"images": [
|
||||
"images/test-image.tar",
|
||||
"images/vuln-image.tar",
|
||||
"images/vuln-with-vex.tar"
|
||||
]
|
||||
},
|
||||
"integrity": {
|
||||
"algorithm": "SHA-256",
|
||||
"manifestDigest": "placeholder"
|
||||
}
|
||||
}
|
||||
45
tests/fixtures/sca/catalogue/README.md
vendored
45
tests/fixtures/sca/catalogue/README.md
vendored
@@ -1,45 +0,0 @@
|
||||
# SCA Failure Catalogue Fixtures
|
||||
|
||||
This directory hosts deterministic fixtures for scanner failure mode regression testing.
|
||||
Each fixture documents a real-world failure pattern that StellaOps must handle correctly.
|
||||
|
||||
## 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
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"id": "fc1-credential-leak",
|
||||
"scanner": "grype",
|
||||
"feed": "offline-cache-2025-11-30",
|
||||
"expected_findings": [
|
||||
{"purl": "pkg:docker/example@1.0.0", "cve": "CVE-2024-9999", "status": "present"}
|
||||
]
|
||||
}
|
||||
1
tests/fixtures/sca/catalogue/fc1/input.txt
vendored
1
tests/fixtures/sca/catalogue/fc1/input.txt
vendored
@@ -1 +0,0 @@
|
||||
input stub for fc1
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"payloadType": "application/json",
|
||||
"payload": "ewogICJpZCI6ICJmYzEtY3JlZGVudGlhbC1sZWFrIiwKICAic2Nhbm5lciI6ICJncnlwZSIsCiAgImZlZWQiOiAib2ZmbGluZS1jYWNoZS0yMDI1LTExLTMwIiwKICAiZXhwZWN0ZWRfZmluZGluZ3MiOiBbCiAgICB7InB1cmwiOiAicGtnOmRvY2tlci9leGFtcGxlQDEuMC4wIiwgImN2ZSI6ICJDVkUtMjAyNC05OTk5IiwgInN0YXR1cyI6ICJwcmVzZW50In0KICBdCn0K",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "stub-key-id",
|
||||
"sig": "stub-signature"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
stub-signature
|
||||
62
tests/fixtures/sca/catalogue/fc10/expected.json
vendored
62
tests/fixtures/sca/catalogue/fc10/expected.json
vendored
@@ -1,62 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
]
|
||||
}
|
||||
33
tests/fixtures/sca/catalogue/fc10/input.txt
vendored
33
tests/fixtures/sca/catalogue/fc10/input.txt
vendored
@@ -1,33 +0,0 @@
|
||||
# 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
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"payloadType": "application/json",
|
||||
"payload": "ewogICJpZCI6ICJmYzEwLWN2ZS1zcGxpdC1tZXJnZSIsCiAgIm5hbWUiOiAiQ1ZFIFNwbGl0L01lcmdlIEZhaWx1cmUgQ2FzZSIsCiAgImRlc2NyaXB0aW9uIjogIlNpbmdsZSB2dWxuZXJhYmlsaXR5IHNwbGl0IGFjcm9zcyBtdWx0aXBsZSBDVkVzIG9yIG11bHRpcGxlIHZ1bG5lcmFiaWxpdGllcyBtZXJnZWQgaW50byBvbmUuIE5WRC9NSVRSRSBzb21ldGltZXMgc3BsaXRzIG9yIG1lcmdlcyBDVkVzIGFmdGVyIGluaXRpYWwgYXNzaWdubWVudCwgY2F1c2luZyB0cmFja2luZyBpc3N1ZXMuIiwKICAic2Nhbm5lciI6ICJncnlwZSIsCiAgImZlZWQiOiAib2ZmbGluZS1jYWNoZS0yMDI1LTEyLTE2IiwKICAiZmFpbHVyZV9tb2RlIjogewogICAgImNhdGVnb3J5IjogImN2ZV90cmFja2luZyIsCiAgICAicm9vdF9jYXVzZSI6ICJDVkUgcmVhc3NpZ25tZW50IG5vdCBwcm9wZXJseSB0cmFja2VkIGluIHZ1bG5lcmFiaWxpdHkgZGF0YWJhc2UiLAogICAgImFmZmVjdGVkX3NjYW5uZXJzIjogWyJncnlwZSIsICJ0cml2eSIsICJzeWZ0Il0sCiAgICAic2V2ZXJpdHkiOiAiaGlnaCIKICB9LAogICJpbnB1dCI6IHsKICAgICJ0eXBlIjogInNib20iLAogICAgInBhY2thZ2VzIjogWwogICAgICB7InB1cmwiOiAicGtnOm5wbS9sb2Rhc2hANC4xNy4xNSIsICJub3RlIjogIkNWRSBzcGxpdCBjYXNlIn0sCiAgICAgIHsicHVybCI6ICJwa2c6bWF2ZW4vb3JnLnNwcmluZ2ZyYW1ld29yay9zcHJpbmctY29yZUA1LjMuMTgiLCAibm90ZSI6ICJDVkUgbWVyZ2UgY2FzZSJ9LAogICAgICB7InB1cmwiOiAicGtnOnB5cGkvcGlsbG93QDkuMC4wIiwgIm5vdGUiOiAiQ1ZFIGNoYWluIGNhc2UifQogICAgXQogIH0sCiAgImN2ZV9jYXNlcyI6IHsKICAgICJzcGxpdCI6IHsKICAgICAgImRlc2NyaXB0aW9uIjogIk9yaWdpbmFsIENWRS0yMDIwLTgyMDMgd2FzIHNwbGl0IGludG8gQ1ZFLTIwMjAtODIwMywgQ1ZFLTIwMjAtMjg1MDAsIENWRS0yMDIxLTIzMzM3IGZvciBsb2Rhc2giLAogICAgICAib3JpZ2luYWxfY3ZlIjogIkNWRS0yMDIwLTgyMDMiLAogICAgICAic3BsaXRfY3ZlcyI6IFsiQ1ZFLTIwMjAtODIwMyIsICJDVkUtMjAyMC0yODUwMCIsICJDVkUtMjAyMS0yMzMzNyJdLAogICAgICAiYWZmZWN0ZWRfcGFja2FnZSI6ICJwa2c6bnBtL2xvZGFzaEA0LjE3LjE1IgogICAgfSwKICAgICJtZXJnZSI6IHsKICAgICAgImRlc2NyaXB0aW9uIjogIkNWRS0yMDIyLTIyOTY1IChTcHJpbmc0U2hlbGwpIGVuY29tcGFzc2VzIHdoYXQgd2FzIGluaXRpYWxseSB0cmFja2VkIGFzIG11bHRpcGxlIGlzc3VlcyIsCiAgICAgICJtZXJnZWRfY3ZlcyI6IFsiQ1ZFLTIwMjItMjI5NjMiLCAiQ1ZFLTIwMjItMjI5NjUiXSwKICAgICAgImNhbm9uaWNhbF9jdmUiOiAiQ1ZFLTIwMjItMjI5NjUiLAogICAgICAiYWZmZWN0ZWRfcGFja2FnZSI6ICJwa2c6bWF2ZW4vb3JnLnNwcmluZ2ZyYW1ld29yay9zcHJpbmctY29yZUA1LjMuMTgiCiAgICB9LAogICAgImNoYWluIjogewogICAgICAiZGVzY3JpcHRpb24iOiAiUGlsbG93IGhhcyB2dWxuZXJhYmlsaXR5IGNoYWluIHdoZXJlIG9uZSBDVkUgbGVhZHMgdG8gYW5vdGhlciIsCiAgICAgICJjdmVfY2hhaW4iOiBbIkNWRS0yMDIyLTIyODE1IiwgIkNWRS0yMDIyLTIyODE2IiwgIkNWRS0yMDIyLTIyODE3Il0sCiAgICAgICJhZmZlY3RlZF9wYWNrYWdlIjogInBrZzpweXBpL3BpbGxvd0A5LjAuMCIKICAgIH0KICB9LAogICJleHBlY3RlZF9maW5kaW5ncyI6IFsKICAgIHsicHVybCI6ICJwa2c6bnBtL2xvZGFzaEA0LjE3LjE1IiwgImN2ZSI6ICJDVkUtMjAyMC04MjAzIiwgInN0YXR1cyI6ICJwcmVzZW50In0sCiAgICB7InB1cmwiOiAicGtnOm5wbS9sb2Rhc2hANC4xNy4xNSIsICJjdmUiOiAiQ1ZFLTIwMjAtMjg1MDAiLCAic3RhdHVzIjogInByZXNlbnQifSwKICAgIHsicHVybCI6ICJwa2c6bnBtL2xvZGFzaEA0LjE3LjE1IiwgImN2ZSI6ICJDVkUtMjAyMS0yMzMzNyIsICJzdGF0dXMiOiAicHJlc2VudCJ9LAogICAgeyJwdXJsIjogInBrZzptYXZlbi9vcmcuc3ByaW5nZnJhbWV3b3JrL3NwcmluZy1jb3JlQDUuMy4xOCIsICJjdmUiOiAiQ1ZFLTIwMjItMjI5NjUiLCAic3RhdHVzIjogInByZXNlbnQifSwKICAgIHsicHVybCI6ICJwa2c6cHlwaS9waWxsb3dAOS4wLjAiLCAiY3ZlIjogIkNWRS0yMDIyLTIyODE1IiwgInN0YXR1cyI6ICJwcmVzZW50In0sCiAgICB7InB1cmwiOiAicGtnOnB5cGkvcGlsbG93QDkuMC4wIiwgImN2ZSI6ICJDVkUtMjAyMi0yMjgxNiIsICJzdGF0dXMiOiAicHJlc2VudCJ9LAogICAgeyJwdXJsIjogInBrZzpweXBpL3BpbGxvd0A5LjAuMCIsICJjdmUiOiAiQ1ZFLTIwMjItMjI4MTciLCAic3RhdHVzIjogInByZXNlbnQifQogIF0sCiAgImRldGVjdGlvbl9yZXF1aXJlbWVudHMiOiB7CiAgICAidHJhY2tfY3ZlX2FsaWFzZXMiOiB0cnVlLAogICAgImhhbmRsZV9jdmVfc3BsaXRzIjogdHJ1ZSwKICAgICJoYW5kbGVfY3ZlX21lcmdlcyI6IHRydWUsCiAgICAidHJhY2tfY3ZlX2NoYWlucyI6IHRydWUsCiAgICAidXNlX29zdl9hbGlhc2VzIjogdHJ1ZQogIH0sCiAgInRlc3RfYXNzZXJ0aW9ucyI6IFsKICAgICJBbGwgQ1ZFcyBmcm9tIHNwbGl0IHZ1bG5lcmFiaWxpdGllcyBtdXN0IGJlIHJlcG9ydGVkIiwKICAgICJNZXJnZWQgQ1ZFcyBzaG91bGQgdXNlIGNhbm9uaWNhbCBDVkUgSUQiLAogICAgIkNWRSBhbGlhc2VzIG11c3QgYmUgdHJhY2tlZCAoZS5nLiwgdmlhIE9TVikiLAogICAgIk5vIGR1cGxpY2F0ZSBmaW5kaW5ncyBmb3Igc2FtZSB1bmRlcmx5aW5nIGlzc3VlIgogIF0KfQo=",
|
||||
"signatures": [
|
||||
{
|
||||
"sig": "stub-signature",
|
||||
"keyid": "stub-key-id"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"id": "fc2-trivy-offline-schema",
|
||||
"scanner": "trivy",
|
||||
"feed": "offline-cache-2025-11-30",
|
||||
"expected_errors": [
|
||||
{"code": "SCHEMA_MISMATCH", "message": "offline DB schema mismatch"}
|
||||
]
|
||||
}
|
||||
1
tests/fixtures/sca/catalogue/fc2/input.txt
vendored
1
tests/fixtures/sca/catalogue/fc2/input.txt
vendored
@@ -1 +0,0 @@
|
||||
input stub for fc2
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"payloadType": "application/json",
|
||||
"payload": "ewogICJpZCI6ICJmYzItdHJpdnktb2ZmbGluZS1zY2hlbWEiLAogICJzY2FubmVyIjogInRyaXZ5IiwKICAiZmVlZCI6ICJvZmZsaW5lLWNhY2hlLTIwMjUtMTEtMzAiLAogICJleHBlY3RlZF9lcnJvcnMiOiBbCiAgICB7ImNvZGUiOiAiU0NIRU1BX01JU01BVENIIiwgIm1lc3NhZ2UiOiAib2ZmbGluZSBEQiBzY2hlbWEgbWlzbWF0Y2gifQogIF0KfQo=",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "stub-key-id",
|
||||
"sig": "stub-signature"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
stub-signature
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"id": "fc3-sbom-parity-drift",
|
||||
"scanner": "syft",
|
||||
"feed": "offline-cache-2025-11-30",
|
||||
"expected_findings": [
|
||||
{"purl": "pkg:docker/example@1.0.0", "issue": "sbom_parity_drift"}
|
||||
]
|
||||
}
|
||||
1
tests/fixtures/sca/catalogue/fc3/input.txt
vendored
1
tests/fixtures/sca/catalogue/fc3/input.txt
vendored
@@ -1 +0,0 @@
|
||||
input stub for fc3
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"payloadType": "application/json",
|
||||
"payload": "ewogICJpZCI6ICJmYzMtc2JvbS1wYXJpdHktZHJpZnQiLAogICJzY2FubmVyIjogInN5ZnQiLAogICJmZWVkIjogIm9mZmxpbmUtY2FjaGUtMjAyNS0xMS0zMCIsCiAgImV4cGVjdGVkX2ZpbmRpbmdzIjogWwogICAgeyJwdXJsIjogInBrZzpkb2NrZXIvZXhhbXBsZUAxLjAuMCIsICJpc3N1ZSI6ICJzYm9tX3Bhcml0eV9kcmlmdCJ9CiAgXQp9Cg==",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "stub-key-id",
|
||||
"sig": "stub-signature"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
stub-signature
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"id": "fc4-grype-version-divergence",
|
||||
"scanner": "grype",
|
||||
"feed": "offline-cache-2025-11-30",
|
||||
"expected_warnings": [
|
||||
{"code": "VERSION_DIVERGENCE", "message": "scanner version drift detected"}
|
||||
]
|
||||
}
|
||||
1
tests/fixtures/sca/catalogue/fc4/input.txt
vendored
1
tests/fixtures/sca/catalogue/fc4/input.txt
vendored
@@ -1 +0,0 @@
|
||||
input stub for fc4
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"payloadType": "application/json",
|
||||
"payload": "ewogICJpZCI6ICJmYzQtZ3J5cGUtdmVyc2lvbi1kaXZlcmdlbmNlIiwKICAic2Nhbm5lciI6ICJncnlwZSIsCiAgImZlZWQiOiAib2ZmbGluZS1jYWNoZS0yMDI1LTExLTMwIiwKICAiZXhwZWN0ZWRfd2FybmluZ3MiOiBbCiAgICB7ImNvZGUiOiAiVkVSU0lPTl9ESVZFUkdFTkNFIiwgIm1lc3NhZ2UiOiAic2Nhbm5lciB2ZXJzaW9uIGRyaWZ0IGRldGVjdGVkIn0KICBdCn0K",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "stub-key-id",
|
||||
"sig": "stub-signature"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
stub-signature
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"id": "fc5-inconsistent-detection",
|
||||
"scanner": "grype",
|
||||
"feed": "offline-cache-2025-11-30",
|
||||
"expected_findings": [
|
||||
{"purl": "pkg:docker/example@1.0.0", "issue": "inconsistent_detection"}
|
||||
]
|
||||
}
|
||||
1
tests/fixtures/sca/catalogue/fc5/input.txt
vendored
1
tests/fixtures/sca/catalogue/fc5/input.txt
vendored
@@ -1 +0,0 @@
|
||||
input stub for fc5
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"payloadType": "application/json",
|
||||
"payload": "ewogICJpZCI6ICJmYzUtaW5jb25zaXN0ZW50LWRldGVjdGlvbiIsCiAgInNjYW5uZXIiOiAiZ3J5cGUiLAogICJmZWVkIjogIm9mZmxpbmUtY2FjaGUtMjAyNS0xMS0zMCIsCiAgImV4cGVjdGVkX2ZpbmRpbmdzIjogWwogICAgeyJwdXJsIjogInBrZzpkb2NrZXIvZXhhbXBsZUAxLjAuMCIsICJpc3N1ZSI6ICJpbmNvbnNpc3RlbnRfZGV0ZWN0aW9uIn0KICBdCn0K",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "stub-key-id",
|
||||
"sig": "stub-signature"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
stub-signature
|
||||
45
tests/fixtures/sca/catalogue/fc6/expected.json
vendored
45
tests/fixtures/sca/catalogue/fc6/expected.json
vendored
@@ -1,45 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
]
|
||||
}
|
||||
26
tests/fixtures/sca/catalogue/fc6/input.txt
vendored
26
tests/fixtures/sca/catalogue/fc6/input.txt
vendored
@@ -1,26 +0,0 @@
|
||||
# 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
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"payloadType": "application/json",
|
||||
"payload": "ewogICJpZCI6ICJmYzYtamF2YS1zaGFkb3ctamFyIiwKICAibmFtZSI6ICJKYXZhIFNoYWRvdyBKQVIgRmFpbHVyZSBDYXNlIiwKICAiZGVzY3JpcHRpb24iOiAiRmF0L3ViZXIgSkFScyB3aXRoIHNoYWRlZCBkZXBlbmRlbmNpZXMgbm90IGNvcnJlY3RseSBhbmFseXplZC4gTWF2ZW4gc2hhZGUgcGx1Z2luIG9yIEdyYWRsZSBzaGFkb3cgY2FuIHJlbG9jYXRlIGNsYXNzZXMsIGNhdXNpbmcgc2Nhbm5lcnMgdG8gbWlzcyB2dWxuZXJhYmxlIGRlcGVuZGVuY2llcyB0aGF0IGhhdmUgYmVlbiByZXBhY2thZ2VkIHVuZGVyIGRpZmZlcmVudCBwYWNrYWdlIG5hbWVzLiIsCiAgInNjYW5uZXIiOiAic3lmdCIsCiAgImZlZWQiOiAib2ZmbGluZS1jYWNoZS0yMDI1LTEyLTE2IiwKICAiZmFpbHVyZV9tb2RlIjogewogICAgImNhdGVnb3J5IjogImRlcGVuZGVuY3lfbWFza2luZyIsCiAgICAicm9vdF9jYXVzZSI6ICJTaGFkZWQgSkFSIGFuYWx5c2lzIGZhaWxzIHRvIGRldGVjdCByZWxvY2F0ZWQgdnVsbmVyYWJsZSBjbGFzc2VzIiwKICAgICJhZmZlY3RlZF9zY2FubmVycyI6IFsic3lmdCIsICJncnlwZSIsICJ0cml2eSJdLAogICAgInNldmVyaXR5IjogImhpZ2giCiAgfSwKICAiaW5wdXQiOiB7CiAgICAidHlwZSI6ICJqYXIiLAogICAgImZpbGUiOiAic2FtcGxlLXViZXIuamFyIiwKICAgICJidWlsZF90b29sIjogIm1hdmVuLXNoYWRlLXBsdWdpbiIsCiAgICAib3JpZ2luYWxfZGVwZW5kZW5jaWVzIjogWwogICAgICB7Imdyb3VwSWQiOiAib3JnLmFwYWNoZS5sb2dnaW5nLmxvZzRqIiwgImFydGlmYWN0SWQiOiAibG9nNGotY29yZSIsICJ2ZXJzaW9uIjogIjIuMTQuMSJ9LAogICAgICB7Imdyb3VwSWQiOiAiY29tLmdvb2dsZS5ndWF2YSIsICJhcnRpZmFjdElkIjogImd1YXZhIiwgInZlcnNpb24iOiAiMjAuMCJ9LAogICAgICB7Imdyb3VwSWQiOiAib3JnLnlhbWwiLCAiYXJ0aWZhY3RJZCI6ICJzbmFrZXlhbWwiLCAidmVyc2lvbiI6ICIxLjI2In0KICAgIF0sCiAgICAic2hhZGVkX3BhY2thZ2VzIjogWwogICAgICB7Im9yaWdpbmFsIjogIm9yZy5hcGFjaGUubG9nZ2luZy5sb2c0aiIsICJyZWxvY2F0ZWQiOiAiY29tLmV4YW1wbGUuc2hhZGVkLmxvZzRqIn0sCiAgICAgIHsib3JpZ2luYWwiOiAiY29tLmdvb2dsZS5ndWF2YSIsICJyZWxvY2F0ZWQiOiAiY29tLmV4YW1wbGUuc2hhZGVkLmd1YXZhIn0sCiAgICAgIHsib3JpZ2luYWwiOiAib3JnLnlhbWwuc25ha2V5YW1sIiwgInJlbG9jYXRlZCI6ICJjb20uZXhhbXBsZS5zaGFkZWQueWFtbCJ9CiAgICBdCiAgfSwKICAiZXhwZWN0ZWRfZmluZGluZ3MiOiBbCiAgICB7InB1cmwiOiAicGtnOm1hdmVuL29yZy5hcGFjaGUubG9nZ2luZy5sb2c0ai9sb2c0ai1jb3JlQDIuMTQuMSIsICJjdmUiOiAiQ1ZFLTIwMjEtNDQyMjgiLCAic3RhdHVzIjogInByZXNlbnQiLCAic2V2ZXJpdHkiOiAiY3JpdGljYWwiLCAibm90ZSI6ICJMb2c0U2hlbGwgLSBtdXN0IGJlIGRldGVjdGVkIGV2ZW4gd2hlbiBzaGFkZWQifSwKICAgIHsicHVybCI6ICJwa2c6bWF2ZW4vb3JnLmFwYWNoZS5sb2dnaW5nLmxvZzRqL2xvZzRqLWNvcmVAMi4xNC4xIiwgImN2ZSI6ICJDVkUtMjAyMS00NTA0NiIsICJzdGF0dXMiOiAicHJlc2VudCIsICJzZXZlcml0eSI6ICJjcml0aWNhbCJ9LAogICAgeyJwdXJsIjogInBrZzptYXZlbi9jb20uZ29vZ2xlLmd1YXZhL2d1YXZhQDIwLjAiLCAiY3ZlIjogIkNWRS0yMDE4LTEwMjM3IiwgInN0YXR1cyI6ICJwcmVzZW50IiwgInNldmVyaXR5IjogIm1lZGl1bSJ9LAogICAgeyJwdXJsIjogInBrZzptYXZlbi9vcmcueWFtbC9zbmFrZXlhbWxAMS4yNiIsICJjdmUiOiAiQ1ZFLTIwMjItMTQ3MSIsICJzdGF0dXMiOiAicHJlc2VudCIsICJzZXZlcml0eSI6ICJoaWdoIn0KICBdLAogICJkZXRlY3Rpb25fcmVxdWlyZW1lbnRzIjogewogICAgIm11c3RfZGV0ZWN0X3NoYWRlZCI6IHRydWUsCiAgICAiYW5hbHl6ZV9qYXJfY29udGVudHMiOiB0cnVlLAogICAgImNoZWNrX3BvbV9wcm9wZXJ0aWVzIjogdHJ1ZSwKICAgICJzY2FuX21hbmlmZXN0X21mIjogdHJ1ZQogIH0sCiAgInRlc3RfYXNzZXJ0aW9ucyI6IFsKICAgICJBbGwgZXhwZWN0ZWQgQ1ZFcyBtdXN0IGJlIGRldGVjdGVkIHJlZ2FyZGxlc3Mgb2YgY2xhc3MgcmVsb2NhdGlvbiIsCiAgICAiT3JpZ2luYWwgYXJ0aWZhY3QgY29vcmRpbmF0ZXMgbXVzdCBiZSByZXNvbHZlZCBmcm9tIE1FVEEtSU5GIiwKICAgICJTaGFkZWQgcGFja2FnZSBuYW1lcyBzaG91bGQgbm90IHByZXZlbnQgdnVsbmVyYWJpbGl0eSBtYXRjaGluZyIKICBdCn0K",
|
||||
"signatures": [
|
||||
{
|
||||
"sig": "stub-signature",
|
||||
"keyid": "stub-key-id"
|
||||
}
|
||||
]
|
||||
}
|
||||
51
tests/fixtures/sca/catalogue/fc7/expected.json
vendored
51
tests/fixtures/sca/catalogue/fc7/expected.json
vendored
@@ -1,51 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
]
|
||||
}
|
||||
31
tests/fixtures/sca/catalogue/fc7/input.txt
vendored
31
tests/fixtures/sca/catalogue/fc7/input.txt
vendored
@@ -1,31 +0,0 @@
|
||||
# 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
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"payloadType": "application/json",
|
||||
"payload": "ewogICJpZCI6ICJmYzctZG90bmV0LXRyYW5zaXRpdmUtcGlubmluZyIsCiAgIm5hbWUiOiAiLk5FVCBUcmFuc2l0aXZlIFBpbm5pbmcgRmFpbHVyZSBDYXNlIiwKICAiZGVzY3JpcHRpb24iOiAiVHJhbnNpdGl2ZSBkZXBlbmRlbmN5IHZlcnNpb24gY29uZmxpY3RzIGluIC5ORVQgcHJvamVjdHMgd2hlcmUgcGFja2FnZXMubG9jay5qc29uIHBpbnMgZGlmZmVyZW50IHZlcnNpb25zIHRoYW4gd2hhdCdzIGFjdHVhbGx5IHJlc29sdmVkLiBDZW50cmFsIFBhY2thZ2UgTWFuYWdlbWVudCAoQ1BNKSBhbmQgdHJhbnNpdGl2ZSBwaW5uaW5nIGNhbiBjYXVzZSBkaXNjcmVwYW5jaWVzLiIsCiAgInNjYW5uZXIiOiAic3lmdCIsCiAgImZlZWQiOiAib2ZmbGluZS1jYWNoZS0yMDI1LTEyLTE2IiwKICAiZmFpbHVyZV9tb2RlIjogewogICAgImNhdGVnb3J5IjogInZlcnNpb25fbWlzbWF0Y2giLAogICAgInJvb3RfY2F1c2UiOiAiVHJhbnNpdGl2ZSBkZXBlbmRlbmN5IHJlc29sdXRpb24gZGlmZmVycyBiZXR3ZWVuIHJlc3RvcmUgYW5kIHNjYW4iLAogICAgImFmZmVjdGVkX3NjYW5uZXJzIjogWyJzeWZ0IiwgInRyaXZ5IiwgImdyeXBlIl0sCiAgICAic2V2ZXJpdHkiOiAiaGlnaCIKICB9LAogICJpbnB1dCI6IHsKICAgICJ0eXBlIjogImRvdG5ldF9wcm9qZWN0IiwKICAgICJmaWxlcyI6IFsiU2FtcGxlQXBwLmNzcHJvaiIsICJwYWNrYWdlcy5sb2NrLmpzb24iLCAiRGlyZWN0b3J5LlBhY2thZ2VzLnByb3BzIl0sCiAgICAiZnJhbWV3b3JrIjogIm5ldDguMCIsCiAgICAiZGlyZWN0X2RlcGVuZGVuY2llcyI6IFsKICAgICAgeyJpZCI6ICJNaWNyb3NvZnQuRW50aXR5RnJhbWV3b3JrQ29yZSIsICJ2ZXJzaW9uIjogIjguMC4wIn0sCiAgICAgIHsiaWQiOiAiTmV3dG9uc29mdC5Kc29uIiwgInZlcnNpb24iOiAiMTMuMC4xIn0KICAgIF0sCiAgICAidHJhbnNpdGl2ZV9jb25mbGljdHMiOiBbCiAgICAgIHsKICAgICAgICAicGFja2FnZSI6ICJTeXN0ZW0uVGV4dC5Kc29uIiwKICAgICAgICAibG9ja19maWxlX3ZlcnNpb24iOiAiOC4wLjAiLAogICAgICAgICJhY3R1YWxfcmVzb2x2ZWQiOiAiOC4wLjEiLAogICAgICAgICJyZWFzb24iOiAiQ1BNIG92ZXJyaWRlIgogICAgICB9LAogICAgICB7CiAgICAgICAgInBhY2thZ2UiOiAiTWljcm9zb2Z0LkV4dGVuc2lvbnMuTG9nZ2luZyIsCiAgICAgICAgImxvY2tfZmlsZV92ZXJzaW9uIjogIjguMC4wIiwgCiAgICAgICAgImFjdHVhbF9yZXNvbHZlZCI6ICI3LjAuMCIsCiAgICAgICAgInJlYXNvbiI6ICJUcmFuc2l0aXZlIGZyb20gb2xkZXIgcGFja2FnZSIKICAgICAgfQogICAgXQogIH0sCiAgImV4cGVjdGVkX2ZpbmRpbmdzIjogWwogICAgeyJwdXJsIjogInBrZzpudWdldC9TeXN0ZW0uVGV4dC5Kc29uQDguMC4xIiwgImN2ZSI6ICJDVkUtMjAyNC1YWFhYIiwgInN0YXR1cyI6ICJwcmVzZW50IiwgIm5vdGUiOiAiTXVzdCB1c2UgYWN0dWFsIHJlc29sdmVkIHZlcnNpb24ifSwKICAgIHsicHVybCI6ICJwa2c6bnVnZXQvTWljcm9zb2Z0LkV4dGVuc2lvbnMuTG9nZ2luZ0A3LjAuMCIsICJjdmUiOiAiQ1ZFLTIwMjMtWVlZWSIsICJzdGF0dXMiOiAicHJlc2VudCIsICJub3RlIjogIlRyYW5zaXRpdmUgZG93bmdyYWRlIGRldGVjdGlvbiJ9CiAgXSwKICAiZGV0ZWN0aW9uX3JlcXVpcmVtZW50cyI6IHsKICAgICJ1c2VfbG9ja19maWxlIjogdHJ1ZSwKICAgICJ2ZXJpZnlfdHJhbnNpdGl2ZV9yZXNvbHV0aW9uIjogdHJ1ZSwKICAgICJjaGVja19jcG1fb3ZlcnJpZGVzIjogdHJ1ZSwKICAgICJyZXNvbHZlX3ZlcnNpb25fY29uZmxpY3RzIjogdHJ1ZQogIH0sCiAgInRlc3RfYXNzZXJ0aW9ucyI6IFsKICAgICJTY2FubmVyIG11c3QgdXNlIGFjdHVhbCByZXNvbHZlZCB2ZXJzaW9ucywgbm90IGxvY2sgZmlsZSB2ZXJzaW9ucyB3aGVuIHRoZXkgY29uZmxpY3QiLAogICAgIlRyYW5zaXRpdmUgZG93bmdyYWRlcyBtdXN0IGJlIGRldGVjdGVkIGFuZCBmbGFnZ2VkIiwKICAgICJDUE0gb3ZlcnJpZGVzIG11c3QgYmUgcmVzcGVjdGVkIGluIHZlcnNpb24gcmVzb2x1dGlvbiIKICBdCn0K",
|
||||
"signatures": [
|
||||
{
|
||||
"sig": "stub-signature",
|
||||
"keyid": "stub-key-id"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
# FC8: Docker Multi-Stage Leakage fixture
|
||||
#
|
||||
# Purpose: Ensure scanners attribute packages to the final stage only.
|
||||
# Note: This file is a deterministic text fixture; it is not executed in tests.
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder
|
||||
WORKDIR /src
|
||||
|
||||
# Build-stage only tools (examples): dotnet-sdk-8.0, build-essential, git
|
||||
RUN dotnet --info > /dev/null
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
|
||||
WORKDIR /app
|
||||
|
||||
# Only artifacts copied from builder should appear in final stage.
|
||||
COPY --from=builder /src/ /app/
|
||||
|
||||
ENTRYPOINT ["dotnet", "SampleApp.dll"]
|
||||
52
tests/fixtures/sca/catalogue/fc8/expected.json
vendored
52
tests/fixtures/sca/catalogue/fc8/expected.json
vendored
@@ -1,52 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
]
|
||||
}
|
||||
32
tests/fixtures/sca/catalogue/fc8/input.txt
vendored
32
tests/fixtures/sca/catalogue/fc8/input.txt
vendored
@@ -1,32 +0,0 @@
|
||||
# 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
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"payloadType": "application/json",
|
||||
"payload": "ewogICJpZCI6ICJmYzgtZG9ja2VyLW11bHRpc3RhZ2UtbGVha2FnZSIsCiAgIm5hbWUiOiAiRG9ja2VyIE11bHRpLVN0YWdlIExlYWthZ2UgRmFpbHVyZSBDYXNlIiwKICAiZGVzY3JpcHRpb24iOiAiQnVpbGQtdGltZSBkZXBlbmRlbmNpZXMgbGVha2luZyBpbnRvIHJ1bnRpbWUgaW1hZ2UgYW5hbHlzaXMuIE11bHRpLXN0YWdlIERvY2tlciBidWlsZHMgc2hvdWxkIG9ubHkgcmVwb3J0IHZ1bG5lcmFiaWxpdGllcyBmb3IgcGFja2FnZXMgaW4gdGhlIGZpbmFsIHN0YWdlLCBidXQgc29tZSBzY2FubmVycyBpbmNvcnJlY3RseSBpbmNsdWRlIGJ1aWxkLXN0YWdlIGRlcGVuZGVuY2llcy4iLAogICJzY2FubmVyIjogInRyaXZ5IiwKICAiZmVlZCI6ICJvZmZsaW5lLWNhY2hlLTIwMjUtMTItMTYiLAogICJmYWlsdXJlX21vZGUiOiB7CiAgICAiY2F0ZWdvcnkiOiAic2NvcGVfY29uZnVzaW9uIiwKICAgICJyb290X2NhdXNlIjogIlNjYW5uZXIgYW5hbHl6ZXMgYWxsIGxheWVycyBpbnN0ZWFkIG9mIGZpbmFsIGltYWdlIHN0YXRlIiwKICAgICJhZmZlY3RlZF9zY2FubmVycyI6IFsidHJpdnkiLCAiZ3J5cGUiLCAic3lmdCJdLAogICAgInNldmVyaXR5IjogIm1lZGl1bSIKICB9LAogICJpbnB1dCI6IHsKICAgICJ0eXBlIjogImRvY2tlcmZpbGUiLAogICAgImZpbGUiOiAiRG9ja2VyZmlsZS5tdWx0aXN0YWdlIiwKICAgICJzdGFnZXMiOiBbCiAgICAgIHsKICAgICAgICAibmFtZSI6ICJidWlsZGVyIiwKICAgICAgICAiYmFzZSI6ICJtY3IubWljcm9zb2Z0LmNvbS9kb3RuZXQvc2RrOjguMCIsCiAgICAgICAgInBhY2thZ2VzIjogWwogICAgICAgICAgeyJuYW1lIjogImRvdG5ldC1zZGstOC4wIiwgInR5cGUiOiAib3MiLCAic2NvcGUiOiAiYnVpbGQifSwKICAgICAgICAgIHsibmFtZSI6ICJidWlsZC1lc3NlbnRpYWwiLCAidHlwZSI6ICJvcyIsICJzY29wZSI6ICJidWlsZCJ9CiAgICAgICAgXQogICAgICB9LAogICAgICB7CiAgICAgICAgIm5hbWUiOiAicnVudGltZSIsCiAgICAgICAgImJhc2UiOiAibWNyLm1pY3Jvc29mdC5jb20vZG90bmV0L2FzcG5ldDo4LjAiLAogICAgICAgICJwYWNrYWdlcyI6IFsKICAgICAgICAgIHsibmFtZSI6ICJhc3BuZXRjb3JlLXJ1bnRpbWUtOC4wIiwgInR5cGUiOiAib3MiLCAic2NvcGUiOiAicnVudGltZSJ9LAogICAgICAgICAgeyJuYW1lIjogImxpYnNzbDMiLCAidHlwZSI6ICJvcyIsICJzY29wZSI6ICJydW50aW1lIn0KICAgICAgICBdLAogICAgICAgICJpc19maW5hbCI6IHRydWUKICAgICAgfQogICAgXQogIH0sCiAgImV4cGVjdGVkX2ZpbmRpbmdzIjogWwogICAgeyJwdXJsIjogInBrZzpkZWIvZGViaWFuL2xpYnNzbDNAMy4wLjExIiwgImN2ZSI6ICJDVkUtMjAyNC1SVU5USU1FIiwgInN0YXR1cyI6ICJwcmVzZW50IiwgIm5vdGUiOiAiUnVudGltZSBpbWFnZSB2dWxuZXJhYmlsaXR5IC0gc2hvdWxkIGJlIHJlcG9ydGVkIn0sCiAgICB7InB1cmwiOiAicGtnOmRlYi9kZWJpYW4vYnVpbGQtZXNzZW50aWFsQDEyLjkiLCAiY3ZlIjogIkNWRS0yMDI0LUJVSUxEIiwgInN0YXR1cyI6ICJhYnNlbnQiLCAibm90ZSI6ICJCdWlsZCBzdGFnZSBvbmx5IC0gc2hvdWxkIE5PVCBiZSByZXBvcnRlZCJ9CiAgXSwKICAiZGV0ZWN0aW9uX3JlcXVpcmVtZW50cyI6IHsKICAgICJhbmFseXplX2ZpbmFsX3N0YWdlX29ubHkiOiB0cnVlLAogICAgInRyYWNrX2xheWVyX3Byb3ZlbmFuY2UiOiB0cnVlLAogICAgImV4Y2x1ZGVfYnVpbGRfZGVwZW5kZW5jaWVzIjogdHJ1ZSwKICAgICJyZXNwZWN0X2NvcHlfZnJvbV9kaXJlY3RpdmVzIjogdHJ1ZQogIH0sCiAgInRlc3RfYXNzZXJ0aW9ucyI6IFsKICAgICJPbmx5IHZ1bG5lcmFiaWxpdGllcyBpbiBmaW5hbCBzdGFnZSBwYWNrYWdlcyBzaG91bGQgYmUgcmVwb3J0ZWQiLAogICAgIkJ1aWxkLXN0YWdlLW9ubHkgcGFja2FnZXMgbXVzdCBub3QgYXBwZWFyIGluIGZpbmRpbmdzIiwKICAgICJDT1BZIC0tZnJvbSBkaXJlY3RpdmVzIG11c3QgYmUgdHJhY2VkIGNvcnJlY3RseSIsCiAgICAiTGF5ZXIgc3F1YXNoaW5nIG11c3Qgbm90IGxlYWsgaW50ZXJtZWRpYXRlIGNvbnRlbnQiCiAgXQp9Cg==",
|
||||
"signatures": [
|
||||
{
|
||||
"sig": "stub-signature",
|
||||
"keyid": "stub-key-id"
|
||||
}
|
||||
]
|
||||
}
|
||||
41
tests/fixtures/sca/catalogue/fc9/expected.json
vendored
41
tests/fixtures/sca/catalogue/fc9/expected.json
vendored
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
]
|
||||
}
|
||||
29
tests/fixtures/sca/catalogue/fc9/input.txt
vendored
29
tests/fixtures/sca/catalogue/fc9/input.txt
vendored
@@ -1,29 +0,0 @@
|
||||
# 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
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"payloadType": "application/json",
|
||||
"payload": "ewogICJpZCI6ICJmYzktcHVybC1uYW1lc3BhY2UtY29sbGlzaW9uIiwKICAibmFtZSI6ICJQVVJMIE5hbWVzcGFjZSBDb2xsaXNpb24gRmFpbHVyZSBDYXNlIiwKICAiZGVzY3JpcHRpb24iOiAiRGlmZmVyZW50IGVjb3N5c3RlbXMgd2l0aCBzYW1lIHBhY2thZ2UgbmFtZXMgY2F1c2luZyBpbmNvcnJlY3QgdnVsbmVyYWJpbGl0eSBhdHRyaWJ1dGlvbi4gRm9yIGV4YW1wbGUsICdyZXF1ZXN0cycgZXhpc3RzIGluIGJvdGggbnBtIGFuZCBweXBpIHdpdGggY29tcGxldGVseSBkaWZmZXJlbnQgY29kZWJhc2VzIGFuZCB2dWxuZXJhYmlsaXRpZXMuIiwKICAic2Nhbm5lciI6ICJncnlwZSIsCiAgImZlZWQiOiAib2ZmbGluZS1jYWNoZS0yMDI1LTEyLTE2IiwKICAiZmFpbHVyZV9tb2RlIjogewogICAgImNhdGVnb3J5IjogImlkZW50aXR5X2NvbmZ1c2lvbiIsCiAgICAicm9vdF9jYXVzZSI6ICJQYWNrYWdlIG5hbWUgbWF0Y2hlZCB3aXRob3V0IGVjb3N5c3RlbSBxdWFsaWZpZXIiLAogICAgImFmZmVjdGVkX3NjYW5uZXJzIjogWyJncnlwZSIsICJ0cml2eSIsICJzeWZ0Il0sCiAgICAic2V2ZXJpdHkiOiAiY3JpdGljYWwiCiAgfSwKICAiaW5wdXQiOiB7CiAgICAidHlwZSI6ICJtaXhlZF9zYm9tIiwKICAgICJlY29zeXN0ZW1zIjogWyJucG0iLCAicHlwaSIsICJjYXJnbyIsICJudWdldCJdLAogICAgInBhY2thZ2VzIjogWwogICAgICB7Im5hbWUiOiAicmVxdWVzdHMiLCAidmVyc2lvbiI6ICIyLjI4LjAiLCAiZWNvc3lzdGVtIjogInB5cGkiLCAicHVybCI6ICJwa2c6cHlwaS9yZXF1ZXN0c0AyLjI4LjAifSwKICAgICAgeyJuYW1lIjogInJlcXVlc3RzIiwgInZlcnNpb24iOiAiMC4zLjAiLCAiZWNvc3lzdGVtIjogIm5wbSIsICJwdXJsIjogInBrZzpucG0vcmVxdWVzdHNAMC4zLjAifSwKICAgICAgeyJuYW1lIjogImpzb24iLCAidmVyc2lvbiI6ICIxMS4wLjAiLCAiZWNvc3lzdGVtIjogIm5wbSIsICJwdXJsIjogInBrZzpucG0vanNvbkAxMS4wLjAifSwKICAgICAgeyJuYW1lIjogImpzb24iLCAidmVyc2lvbiI6ICIwLjEuMCIsICJlY29zeXN0ZW0iOiAiY2FyZ28iLCAicHVybCI6ICJwa2c6Y2FyZ28vanNvbkAwLjEuMCJ9LAogICAgICB7Im5hbWUiOiAiU3lzdGVtLlRleHQuSnNvbiIsICJ2ZXJzaW9uIjogIjguMC4wIiwgImVjb3N5c3RlbSI6ICJudWdldCIsICJwdXJsIjogInBrZzpudWdldC9TeXN0ZW0uVGV4dC5Kc29uQDguMC4wIn0KICAgIF0KICB9LAogICJleHBlY3RlZF9maW5kaW5ncyI6IFsKICAgIHsicHVybCI6ICJwa2c6cHlwaS9yZXF1ZXN0c0AyLjI4LjAiLCAiY3ZlIjogIkNWRS0yMDIzLVBZUEkiLCAic3RhdHVzIjogInByZXNlbnQiLCAibm90ZSI6ICJQeVBJIHJlcXVlc3RzIHZ1bG5lcmFiaWxpdHkifSwKICAgIHsicHVybCI6ICJwa2c6bnBtL3JlcXVlc3RzQDAuMy4wIiwgImN2ZSI6ICJDVkUtMjAyMy1OUE0iLCAic3RhdHVzIjogInByZXNlbnQiLCAibm90ZSI6ICJucG0gcmVxdWVzdHMgdnVsbmVyYWJpbGl0eSAtIGRpZmZlcmVudCBwYWNrYWdlIn0sCiAgICB7InB1cmwiOiAicGtnOnB5cGkvcmVxdWVzdHNAMi4yOC4wIiwgImN2ZSI6ICJDVkUtMjAyMy1OUE0iLCAic3RhdHVzIjogImFic2VudCIsICJub3RlIjogIk1VU1QgTk9UIGNyb3NzLW1hdGNoIG5wbSBDVkUgdG8gcHlwaSBwYWNrYWdlIn0KICBdLAogICJkZXRlY3Rpb25fcmVxdWlyZW1lbnRzIjogewogICAgImVjb3N5c3RlbV9xdWFsaWZpZWRfbWF0Y2hpbmciOiB0cnVlLAogICAgInB1cmxfdHlwZV9lbmZvcmNlbWVudCI6IHRydWUsCiAgICAibm9fY3Jvc3NfZWNvc3lzdGVtX21hdGNoaW5nIjogdHJ1ZSwKICAgICJzdHJpY3RfbmFtZXNwYWNlX3ZhbGlkYXRpb24iOiB0cnVlCiAgfSwKICAidGVzdF9hc3NlcnRpb25zIjogWwogICAgIlZ1bG5lcmFiaWxpdGllcyBtdXN0IG9ubHkgbWF0Y2ggcGFja2FnZXMgd2l0aCBjb3JyZWN0IGVjb3N5c3RlbSIsCiAgICAicGtnOnB5cGkvWCBtdXN0IG5ldmVyIG1hdGNoIGFkdmlzb3JpZXMgZm9yIHBrZzpucG0vWCIsCiAgICAiUFVSTCB0eXBlIG11c3QgYmUgcGFydCBvZiB2dWxuZXJhYmlsaXR5IG1hdGNoaW5nIiwKICAgICJDcm9zcy1lY29zeXN0ZW0gZmFsc2UgcG9zaXRpdmVzIGFyZSBjcml0aWNhbCBmYWlsdXJlcyIKICBdCn0K",
|
||||
"signatures": [
|
||||
{
|
||||
"sig": "stub-signature",
|
||||
"keyid": "stub-key-id"
|
||||
}
|
||||
]
|
||||
}
|
||||
55
tests/fixtures/sca/catalogue/inputs.lock
vendored
55
tests/fixtures/sca/catalogue/inputs.lock
vendored
@@ -1,55 +0,0 @@
|
||||
scanner_versions:
|
||||
grype: "0.76.1"
|
||||
trivy: "0.49.1"
|
||||
syft: "1.1.0"
|
||||
feed_snapshot: "offline-cache-2025-12-16"
|
||||
seeds:
|
||||
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"
|
||||
|
||||
Reference in New Issue
Block a user