tests fixes and some product advisories tunes ups
This commit is contained in:
58
tests/fixtures/sca/catalogue/fc10/expected.json
vendored
Normal file
58
tests/fixtures/sca/catalogue/fc10/expected.json
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"id": "fc10-cve-split-merge-chain",
|
||||
"description": "CVE Split/Merge/Chain: Complex CVE relationships where original CVEs are split into multiple, merged from multiple sources, or form dependency chains. Scanner must track these relationships for accurate remediation.",
|
||||
"failure_mode": {
|
||||
"category": "cve-relationship-confusion",
|
||||
"severity": "critical",
|
||||
"impact": "Incomplete remediation - fixing one CVE may not address related split CVEs",
|
||||
"root_cause": "CVE lifecycle changes (splits, merges) not tracked across advisory updates",
|
||||
"detection_strategy": "Maintain CVE relationship graph, track splits/merges/chains from NVD and vendor advisories"
|
||||
},
|
||||
"input": {
|
||||
"ecosystem": "java",
|
||||
"package": "org.apache.logging.log4j:log4j-core",
|
||||
"scenario": "Log4Shell (CVE-2021-44228) spawned related CVEs through splits and chains"
|
||||
},
|
||||
"expected_findings": [
|
||||
{
|
||||
"finding_type": "cve_split_merge_chain",
|
||||
"package": {
|
||||
"name": "log4j-core",
|
||||
"purl": "pkg:maven/org.apache.logging.log4j/log4j-core@2.14.1"
|
||||
},
|
||||
"cve_relationships": {
|
||||
"primary": "CVE-2021-44228",
|
||||
"related": ["CVE-2021-45046", "CVE-2021-45105", "CVE-2021-44832"]
|
||||
},
|
||||
"recommendation": "Upgrade to log4j-core 2.17.1+ to address all related CVEs"
|
||||
}
|
||||
],
|
||||
"cve_cases": {
|
||||
"split": {
|
||||
"description": "Original CVE split into more specific issues",
|
||||
"original_cve": "CVE-2021-44228",
|
||||
"split_cves": ["CVE-2021-45046", "CVE-2021-45105"],
|
||||
"reason": "Initial fix was incomplete, additional attack vectors discovered"
|
||||
},
|
||||
"merge": {
|
||||
"description": "Multiple reports consolidated into single CVE",
|
||||
"merged_cves": ["GHSA-jfh8-c2jp-5v3q"],
|
||||
"target_cve": "CVE-2021-44228",
|
||||
"reason": "GitHub advisory assigned before NVD CVE"
|
||||
},
|
||||
"chain": {
|
||||
"description": "Vulnerabilities that enable or amplify each other",
|
||||
"cve_chain": ["CVE-2021-44228", "CVE-2021-44832"],
|
||||
"chain_type": "amplification",
|
||||
"reason": "CVE-2021-44832 is RCE via config, enabled by CVE-2021-44228 JNDI"
|
||||
}
|
||||
},
|
||||
"test_vectors": {
|
||||
"log4j_2_14_1_cves": ["CVE-2021-44228", "CVE-2021-45046", "CVE-2021-45105", "CVE-2021-44832"],
|
||||
"log4j_2_15_0_cves": ["CVE-2021-45046", "CVE-2021-45105", "CVE-2021-44832"],
|
||||
"log4j_2_16_0_cves": ["CVE-2021-45105", "CVE-2021-44832"],
|
||||
"log4j_2_17_0_cves": ["CVE-2021-44832"],
|
||||
"log4j_2_17_1_cves": [],
|
||||
"expected_scanner_behavior": "Track CVE relationships, recommend version that addresses ALL related CVEs"
|
||||
}
|
||||
}
|
||||
68
tests/fixtures/sca/catalogue/fc10/input.txt
vendored
Normal file
68
tests/fixtures/sca/catalogue/fc10/input.txt
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
# FC10 - CVE Split/Merge/Chain Test Input
|
||||
# Scenario: Log4Shell and its related CVE relationships
|
||||
|
||||
== pom.xml ==
|
||||
<project>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>vulnerable-app</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.14.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
== CVE Relationship Timeline ==
|
||||
|
||||
2021-12-09: CVE-2021-44228 (Log4Shell) published
|
||||
- CVSS: 10.0 CRITICAL
|
||||
- RCE via JNDI lookup in log messages
|
||||
- Fix: 2.15.0 (disable JNDI by default)
|
||||
|
||||
2021-12-14: CVE-2021-45046 published (SPLIT from 44228)
|
||||
- CVSS: 9.0 CRITICAL
|
||||
- 2.15.0 fix incomplete, DoS still possible
|
||||
- Fix: 2.16.0 (remove JNDI entirely)
|
||||
|
||||
2021-12-18: CVE-2021-45105 published (SPLIT from 45046)
|
||||
- CVSS: 7.5 HIGH
|
||||
- 2.16.0 vulnerable to DoS via recursive lookup
|
||||
- Fix: 2.17.0
|
||||
|
||||
2021-12-28: CVE-2021-44832 published (CHAIN)
|
||||
- CVSS: 6.6 MEDIUM
|
||||
- RCE via JDBC appender configuration
|
||||
- Fix: 2.17.1
|
||||
- Chained: requires config control, amplified by 44228
|
||||
|
||||
== Version Remediation Matrix ==
|
||||
|
||||
Version | CVE-2021-44228 | CVE-2021-45046 | CVE-2021-45105 | CVE-2021-44832
|
||||
2.14.1 | VULNERABLE | VULNERABLE | VULNERABLE | VULNERABLE
|
||||
2.15.0 | FIXED | VULNERABLE | VULNERABLE | VULNERABLE
|
||||
2.16.0 | FIXED | FIXED | VULNERABLE | VULNERABLE
|
||||
2.17.0 | FIXED | FIXED | FIXED | VULNERABLE
|
||||
2.17.1 | FIXED | FIXED | FIXED | FIXED
|
||||
|
||||
== Scanner Failure Modes ==
|
||||
|
||||
1. Reporting only CVE-2021-44228 without split CVEs
|
||||
- User upgrades to 2.15.0 thinking they're safe
|
||||
- Still vulnerable to 45046, 45105, 44832
|
||||
|
||||
2. Missing CVE chain relationships
|
||||
- CVE-2021-44832 seems "medium" severity alone
|
||||
- Combined with 44228 attack vector, becomes critical
|
||||
|
||||
3. Not tracking GHSA -> CVE merges
|
||||
- GHSA-jfh8-c2jp-5v3q was assigned before CVE
|
||||
- Duplicate findings if not properly merged
|
||||
|
||||
== Expected Scanner Behavior ==
|
||||
- Detect log4j-core@2.14.1
|
||||
- Report ALL four CVEs with relationships
|
||||
- Recommend upgrade to 2.17.1 (not just 2.15.0)
|
||||
- Explain CVE split/chain relationships in remediation guidance
|
||||
10
tests/fixtures/sca/catalogue/fc10/manifest.dsse.json
vendored
Normal file
10
tests/fixtures/sca/catalogue/fc10/manifest.dsse.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"payloadType": "application/vnd.stellaops.sca-fixture+json",
|
||||
"payload": "ew0KICAiaWQiOiAiZmMxMC1jdmUtc3BsaXQtbWVyZ2UtY2hhaW4iLA0KICAiZGVzY3JpcHRpb24iOiAiQ1ZFIFNwbGl0L01lcmdlL0NoYWluOiBDb21wbGV4IENWRSByZWxhdGlvbnNoaXBzIHdoZXJlIG9yaWdpbmFsIENWRXMgYXJlIHNwbGl0IGludG8gbXVsdGlwbGUsIG1lcmdlZCBmcm9tIG11bHRpcGxlIHNvdXJjZXMsIG9yIGZvcm0gZGVwZW5kZW5jeSBjaGFpbnMuIFNjYW5uZXIgbXVzdCB0cmFjayB0aGVzZSByZWxhdGlvbnNoaXBzIGZvciBhY2N1cmF0ZSByZW1lZGlhdGlvbi4iLA0KICAiZmFpbHVyZV9tb2RlIjogew0KICAgICJjYXRlZ29yeSI6ICJjdmUtcmVsYXRpb25zaGlwLWNvbmZ1c2lvbiIsDQogICAgInNldmVyaXR5IjogImNyaXRpY2FsIiwNCiAgICAiaW1wYWN0IjogIkluY29tcGxldGUgcmVtZWRpYXRpb24gLSBmaXhpbmcgb25lIENWRSBtYXkgbm90IGFkZHJlc3MgcmVsYXRlZCBzcGxpdCBDVkVzIiwNCiAgICAicm9vdF9jYXVzZSI6ICJDVkUgbGlmZWN5Y2xlIGNoYW5nZXMgKHNwbGl0cywgbWVyZ2VzKSBub3QgdHJhY2tlZCBhY3Jvc3MgYWR2aXNvcnkgdXBkYXRlcyIsDQogICAgImRldGVjdGlvbl9zdHJhdGVneSI6ICJNYWludGFpbiBDVkUgcmVsYXRpb25zaGlwIGdyYXBoLCB0cmFjayBzcGxpdHMvbWVyZ2VzL2NoYWlucyBmcm9tIE5WRCBhbmQgdmVuZG9yIGFkdmlzb3JpZXMiDQogIH0sDQogICJpbnB1dCI6IHsNCiAgICAiZWNvc3lzdGVtIjogImphdmEiLA0KICAgICJwYWNrYWdlIjogIm9yZy5hcGFjaGUubG9nZ2luZy5sb2c0ajpsb2c0ai1jb3JlIiwNCiAgICAic2NlbmFyaW8iOiAiTG9nNFNoZWxsIChDVkUtMjAyMS00NDIyOCkgc3Bhd25lZCByZWxhdGVkIENWRXMgdGhyb3VnaCBzcGxpdHMgYW5kIGNoYWlucyINCiAgfSwNCiAgImV4cGVjdGVkX2ZpbmRpbmdzIjogWw0KICAgIHsNCiAgICAgICJmaW5kaW5nX3R5cGUiOiAiY3ZlX3NwbGl0X21lcmdlX2NoYWluIiwNCiAgICAgICJwYWNrYWdlIjogew0KICAgICAgICAibmFtZSI6ICJsb2c0ai1jb3JlIiwNCiAgICAgICAgInB1cmwiOiAicGtnOm1hdmVuL29yZy5hcGFjaGUubG9nZ2luZy5sb2c0ai9sb2c0ai1jb3JlQDIuMTQuMSINCiAgICAgIH0sDQogICAgICAiY3ZlX3JlbGF0aW9uc2hpcHMiOiB7DQogICAgICAgICJwcmltYXJ5IjogIkNWRS0yMDIxLTQ0MjI4IiwNCiAgICAgICAgInJlbGF0ZWQiOiBbIkNWRS0yMDIxLTQ1MDQ2IiwgIkNWRS0yMDIxLTQ1MTA1IiwgIkNWRS0yMDIxLTQ0ODMyIl0NCiAgICAgIH0sDQogICAgICAicmVjb21tZW5kYXRpb24iOiAiVXBncmFkZSB0byBsb2c0ai1jb3JlIDIuMTcuMSsgdG8gYWRkcmVzcyBhbGwgcmVsYXRlZCBDVkVzIg0KICAgIH0NCiAgXSwNCiAgImN2ZV9jYXNlcyI6IHsNCiAgICAic3BsaXQiOiB7DQogICAgICAiZGVzY3JpcHRpb24iOiAiT3JpZ2luYWwgQ1ZFIHNwbGl0IGludG8gbW9yZSBzcGVjaWZpYyBpc3N1ZXMiLA0KICAgICAgIm9yaWdpbmFsX2N2ZSI6ICJDVkUtMjAyMS00NDIyOCIsDQogICAgICAic3BsaXRfY3ZlcyI6IFsiQ1ZFLTIwMjEtNDUwNDYiLCAiQ1ZFLTIwMjEtNDUxMDUiXSwNCiAgICAgICJyZWFzb24iOiAiSW5pdGlhbCBmaXggd2FzIGluY29tcGxldGUsIGFkZGl0aW9uYWwgYXR0YWNrIHZlY3RvcnMgZGlzY292ZXJlZCINCiAgICB9LA0KICAgICJtZXJnZSI6IHsNCiAgICAgICJkZXNjcmlwdGlvbiI6ICJNdWx0aXBsZSByZXBvcnRzIGNvbnNvbGlkYXRlZCBpbnRvIHNpbmdsZSBDVkUiLA0KICAgICAgIm1lcmdlZF9jdmVzIjogWyJHSFNBLWpmaDgtYzJqcC01djNxIl0sDQogICAgICAidGFyZ2V0X2N2ZSI6ICJDVkUtMjAyMS00NDIyOCIsDQogICAgICAicmVhc29uIjogIkdpdEh1YiBhZHZpc29yeSBhc3NpZ25lZCBiZWZvcmUgTlZEIENWRSINCiAgICB9LA0KICAgICJjaGFpbiI6IHsNCiAgICAgICJkZXNjcmlwdGlvbiI6ICJWdWxuZXJhYmlsaXRpZXMgdGhhdCBlbmFibGUgb3IgYW1wbGlmeSBlYWNoIG90aGVyIiwNCiAgICAgICJjdmVfY2hhaW4iOiBbIkNWRS0yMDIxLTQ0MjI4IiwgIkNWRS0yMDIxLTQ0ODMyIl0sDQogICAgICAiY2hhaW5fdHlwZSI6ICJhbXBsaWZpY2F0aW9uIiwNCiAgICAgICJyZWFzb24iOiAiQ1ZFLTIwMjEtNDQ4MzIgaXMgUkNFIHZpYSBjb25maWcsIGVuYWJsZWQgYnkgQ1ZFLTIwMjEtNDQyMjggSk5ESSINCiAgICB9DQogIH0sDQogICJ0ZXN0X3ZlY3RvcnMiOiB7DQogICAgImxvZzRqXzJfMTRfMV9jdmVzIjogWyJDVkUtMjAyMS00NDIyOCIsICJDVkUtMjAyMS00NTA0NiIsICJDVkUtMjAyMS00NTEwNSIsICJDVkUtMjAyMS00NDgzMiJdLA0KICAgICJsb2c0al8yXzE1XzBfY3ZlcyI6IFsiQ1ZFLTIwMjEtNDUwNDYiLCAiQ1ZFLTIwMjEtNDUxMDUiLCAiQ1ZFLTIwMjEtNDQ4MzIiXSwNCiAgICAibG9nNGpfMl8xNl8wX2N2ZXMiOiBbIkNWRS0yMDIxLTQ1MTA1IiwgIkNWRS0yMDIxLTQ0ODMyIl0sDQogICAgImxvZzRqXzJfMTdfMF9jdmVzIjogWyJDVkUtMjAyMS00NDgzMiJdLA0KICAgICJsb2c0al8yXzE3XzFfY3ZlcyI6IFtdLA0KICAgICJleHBlY3RlZF9zY2FubmVyX2JlaGF2aW9yIjogIlRyYWNrIENWRSByZWxhdGlvbnNoaXBzLCByZWNvbW1lbmQgdmVyc2lvbiB0aGF0IGFkZHJlc3NlcyBBTEwgcmVsYXRlZCBDVkVzIg0KICB9DQp9DQo=",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "stellaops:sca-catalogue:v1",
|
||||
"sig": "fixture-signature-placeholder"
|
||||
}
|
||||
]
|
||||
}
|
||||
41
tests/fixtures/sca/catalogue/fc6/expected.json
vendored
Normal file
41
tests/fixtures/sca/catalogue/fc6/expected.json
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"id": "fc6-phantom-dependency",
|
||||
"description": "Phantom Dependency: A dependency declared in package.json but not actually installed in node_modules. Scanner reports vulnerability for non-existent package.",
|
||||
"failure_mode": {
|
||||
"category": "false-positive",
|
||||
"severity": "medium",
|
||||
"impact": "Noise in vulnerability reports, wasted remediation effort",
|
||||
"root_cause": "Scanner trusts manifest without verifying actual installation",
|
||||
"detection_strategy": "Cross-reference manifest with lockfile and filesystem"
|
||||
},
|
||||
"input": {
|
||||
"ecosystem": "npm",
|
||||
"manifest_file": "package.json",
|
||||
"lockfile": "package-lock.json",
|
||||
"scenario": "Developer added lodash@4.17.20 to package.json but never ran npm install"
|
||||
},
|
||||
"expected_findings": [
|
||||
{
|
||||
"finding_type": "phantom_dependency",
|
||||
"package": {
|
||||
"name": "lodash",
|
||||
"version": "4.17.20",
|
||||
"purl": "pkg:npm/lodash@4.17.20"
|
||||
},
|
||||
"status": "not_installed",
|
||||
"evidence": {
|
||||
"in_manifest": true,
|
||||
"in_lockfile": false,
|
||||
"in_filesystem": false
|
||||
},
|
||||
"related_cves": ["CVE-2021-23337", "CVE-2020-8203"],
|
||||
"recommendation": "Remove from manifest or run npm install to actually install the dependency"
|
||||
}
|
||||
],
|
||||
"test_vectors": {
|
||||
"manifest_declares": "lodash@4.17.20",
|
||||
"lockfile_contains": false,
|
||||
"node_modules_contains": false,
|
||||
"expected_scanner_behavior": "Flag as phantom dependency, do not report CVEs as actionable"
|
||||
}
|
||||
}
|
||||
46
tests/fixtures/sca/catalogue/fc6/input.txt
vendored
Normal file
46
tests/fixtures/sca/catalogue/fc6/input.txt
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# FC6 - Phantom Dependency Test Input
|
||||
# Scenario: lodash declared in package.json but never installed
|
||||
|
||||
== package.json ==
|
||||
{
|
||||
"name": "fc6-test-app",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"lodash": "4.17.20"
|
||||
}
|
||||
}
|
||||
|
||||
== package-lock.json ==
|
||||
{
|
||||
"name": "fc6-test-app",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "fc6-test-app",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2"
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.18.2",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
== Filesystem State ==
|
||||
node_modules/
|
||||
express/
|
||||
package.json
|
||||
index.js
|
||||
# NOTE: lodash/ directory DOES NOT EXIST
|
||||
|
||||
== Expected Scanner Output ==
|
||||
- Should detect lodash@4.17.20 in package.json
|
||||
- Should NOT find lodash in package-lock.json
|
||||
- Should NOT find lodash in node_modules/
|
||||
- Should flag as PHANTOM_DEPENDENCY
|
||||
- Should NOT report CVE-2021-23337 as actionable vulnerability
|
||||
10
tests/fixtures/sca/catalogue/fc6/manifest.dsse.json
vendored
Normal file
10
tests/fixtures/sca/catalogue/fc6/manifest.dsse.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"payloadType": "application/vnd.stellaops.sca-fixture+json",
|
||||
"payload": "ew0KICAiaWQiOiAiZmM2LXBoYW50b20tZGVwZW5kZW5jeSIsDQogICJkZXNjcmlwdGlvbiI6ICJQaGFudG9tIERlcGVuZGVuY3k6IEEgZGVwZW5kZW5jeSBkZWNsYXJlZCBpbiBwYWNrYWdlLmpzb24gYnV0IG5vdCBhY3R1YWxseSBpbnN0YWxsZWQgaW4gbm9kZV9tb2R1bGVzLiBTY2FubmVyIHJlcG9ydHMgdnVsbmVyYWJpbGl0eSBmb3Igbm9uLWV4aXN0ZW50IHBhY2thZ2UuIiwNCiAgImZhaWx1cmVfbW9kZSI6IHsNCiAgICAiY2F0ZWdvcnkiOiAiZmFsc2UtcG9zaXRpdmUiLA0KICAgICJzZXZlcml0eSI6ICJtZWRpdW0iLA0KICAgICJpbXBhY3QiOiAiTm9pc2UgaW4gdnVsbmVyYWJpbGl0eSByZXBvcnRzLCB3YXN0ZWQgcmVtZWRpYXRpb24gZWZmb3J0IiwNCiAgICAicm9vdF9jYXVzZSI6ICJTY2FubmVyIHRydXN0cyBtYW5pZmVzdCB3aXRob3V0IHZlcmlmeWluZyBhY3R1YWwgaW5zdGFsbGF0aW9uIiwNCiAgICAiZGV0ZWN0aW9uX3N0cmF0ZWd5IjogIkNyb3NzLXJlZmVyZW5jZSBtYW5pZmVzdCB3aXRoIGxvY2tmaWxlIGFuZCBmaWxlc3lzdGVtIg0KICB9LA0KICAiaW5wdXQiOiB7DQogICAgImVjb3N5c3RlbSI6ICJucG0iLA0KICAgICJtYW5pZmVzdF9maWxlIjogInBhY2thZ2UuanNvbiIsDQogICAgImxvY2tmaWxlIjogInBhY2thZ2UtbG9jay5qc29uIiwNCiAgICAic2NlbmFyaW8iOiAiRGV2ZWxvcGVyIGFkZGVkIGxvZGFzaEA0LjE3LjIwIHRvIHBhY2thZ2UuanNvbiBidXQgbmV2ZXIgcmFuIG5wbSBpbnN0YWxsIg0KICB9LA0KICAiZXhwZWN0ZWRfZmluZGluZ3MiOiBbDQogICAgew0KICAgICAgImZpbmRpbmdfdHlwZSI6ICJwaGFudG9tX2RlcGVuZGVuY3kiLA0KICAgICAgInBhY2thZ2UiOiB7DQogICAgICAgICJuYW1lIjogImxvZGFzaCIsDQogICAgICAgICJ2ZXJzaW9uIjogIjQuMTcuMjAiLA0KICAgICAgICAicHVybCI6ICJwa2c6bnBtL2xvZGFzaEA0LjE3LjIwIg0KICAgICAgfSwNCiAgICAgICJzdGF0dXMiOiAibm90X2luc3RhbGxlZCIsDQogICAgICAiZXZpZGVuY2UiOiB7DQogICAgICAgICJpbl9tYW5pZmVzdCI6IHRydWUsDQogICAgICAgICJpbl9sb2NrZmlsZSI6IGZhbHNlLA0KICAgICAgICAiaW5fZmlsZXN5c3RlbSI6IGZhbHNlDQogICAgICB9LA0KICAgICAgInJlbGF0ZWRfY3ZlcyI6IFsiQ1ZFLTIwMjEtMjMzMzciLCAiQ1ZFLTIwMjAtODIwMyJdLA0KICAgICAgInJlY29tbWVuZGF0aW9uIjogIlJlbW92ZSBmcm9tIG1hbmlmZXN0IG9yIHJ1biBucG0gaW5zdGFsbCB0byBhY3R1YWxseSBpbnN0YWxsIHRoZSBkZXBlbmRlbmN5Ig0KICAgIH0NCiAgXSwNCiAgInRlc3RfdmVjdG9ycyI6IHsNCiAgICAibWFuaWZlc3RfZGVjbGFyZXMiOiAibG9kYXNoQDQuMTcuMjAiLA0KICAgICJsb2NrZmlsZV9jb250YWlucyI6IGZhbHNlLA0KICAgICJub2RlX21vZHVsZXNfY29udGFpbnMiOiBmYWxzZSwNCiAgICAiZXhwZWN0ZWRfc2Nhbm5lcl9iZWhhdmlvciI6ICJGbGFnIGFzIHBoYW50b20gZGVwZW5kZW5jeSwgZG8gbm90IHJlcG9ydCBDVkVzIGFzIGFjdGlvbmFibGUiDQogIH0NCn0NCg==",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "stellaops:sca-catalogue:v1",
|
||||
"sig": "fixture-signature-placeholder"
|
||||
}
|
||||
]
|
||||
}
|
||||
51
tests/fixtures/sca/catalogue/fc7/expected.json
vendored
Normal file
51
tests/fixtures/sca/catalogue/fc7/expected.json
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"id": "fc7-transitive-depth-confusion",
|
||||
"description": "Transitive Depth Confusion: Deep transitive dependency resolution differs between package managers, causing version mismatch in vulnerability assessment.",
|
||||
"failure_mode": {
|
||||
"category": "version-mismatch",
|
||||
"severity": "high",
|
||||
"impact": "False negatives - vulnerable version not detected due to resolution differences",
|
||||
"root_cause": "Different dependency resolution algorithms between npm/yarn/pnpm or maven/gradle",
|
||||
"detection_strategy": "Compare resolved versions across multiple resolution strategies"
|
||||
},
|
||||
"input": {
|
||||
"ecosystem": "maven",
|
||||
"manifest_file": "pom.xml",
|
||||
"scenario": "Diamond dependency: A->B->D@1.0, A->C->D@2.0, resolution picks D@1.0 which is vulnerable"
|
||||
},
|
||||
"expected_findings": [
|
||||
{
|
||||
"finding_type": "transitive_depth_confusion",
|
||||
"package": {
|
||||
"name": "commons-collections",
|
||||
"version": "3.2.1",
|
||||
"purl": "pkg:maven/commons-collections/commons-collections@3.2.1"
|
||||
},
|
||||
"depth": 4,
|
||||
"resolution_path": [
|
||||
"com.example:app:1.0.0",
|
||||
"org.springframework:spring-core:4.3.25",
|
||||
"commons-logging:commons-logging:1.2",
|
||||
"commons-collections:commons-collections:3.2.1"
|
||||
],
|
||||
"alternate_resolution": {
|
||||
"version": "3.2.2",
|
||||
"path": [
|
||||
"com.example:app:1.0.0",
|
||||
"org.apache.struts:struts2-core:2.5.20",
|
||||
"commons-collections:commons-collections:3.2.2"
|
||||
]
|
||||
},
|
||||
"related_cves": ["CVE-2015-6420"],
|
||||
"recommendation": "Explicitly declare commons-collections:3.2.2 in dependencyManagement to override transitive resolution"
|
||||
}
|
||||
],
|
||||
"test_vectors": {
|
||||
"diamond_root": "com.example:app:1.0.0",
|
||||
"left_branch": "spring-core -> commons-logging -> commons-collections:3.2.1",
|
||||
"right_branch": "struts2-core -> commons-collections:3.2.2",
|
||||
"maven_resolution": "3.2.1 (nearest-wins)",
|
||||
"gradle_resolution": "3.2.2 (highest-wins)",
|
||||
"expected_scanner_behavior": "Detect version ambiguity and flag potential CVE-2015-6420 exposure"
|
||||
}
|
||||
}
|
||||
52
tests/fixtures/sca/catalogue/fc7/input.txt
vendored
Normal file
52
tests/fixtures/sca/catalogue/fc7/input.txt
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
# FC7 - Transitive Depth Confusion Test Input
|
||||
# Scenario: Diamond dependency with version conflict at depth 4
|
||||
|
||||
== pom.xml ==
|
||||
<project>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>app</artifactId>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<dependencies>
|
||||
<!-- Left branch: eventually pulls commons-collections:3.2.1 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>4.3.25.RELEASE</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Right branch: eventually pulls commons-collections:3.2.2 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.struts</groupId>
|
||||
<artifactId>struts2-core</artifactId>
|
||||
<version>2.5.20</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
== Dependency Tree (Maven) ==
|
||||
com.example:app:1.0.0
|
||||
+- org.springframework:spring-core:4.3.25.RELEASE
|
||||
| +- commons-logging:commons-logging:1.2
|
||||
| +- commons-collections:commons-collections:3.2.1 (SELECTED - nearest wins)
|
||||
+- org.apache.struts:struts2-core:2.5.20
|
||||
+- commons-collections:commons-collections:3.2.2 (OMITTED - conflict)
|
||||
|
||||
== Dependency Tree (Gradle - different resolution) ==
|
||||
com.example:app:1.0.0
|
||||
+- org.springframework:spring-core:4.3.25.RELEASE
|
||||
| +- commons-logging:commons-logging:1.2
|
||||
| +- commons-collections:commons-collections:3.2.2 (SELECTED - highest wins)
|
||||
+- org.apache.struts:struts2-core:2.5.20
|
||||
+- commons-collections:commons-collections:3.2.2 (SELECTED)
|
||||
|
||||
== Vulnerability Context ==
|
||||
CVE-2015-6420: commons-collections <= 3.2.1 RCE via deserialization
|
||||
- 3.2.1 is VULNERABLE
|
||||
- 3.2.2 is FIXED
|
||||
|
||||
== Expected Scanner Behavior ==
|
||||
- Should detect diamond dependency pattern
|
||||
- Should identify version ambiguity between resolvers
|
||||
- Should flag CVE-2015-6420 for Maven builds
|
||||
- Should note Gradle builds use safe version
|
||||
10
tests/fixtures/sca/catalogue/fc7/manifest.dsse.json
vendored
Normal file
10
tests/fixtures/sca/catalogue/fc7/manifest.dsse.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"payloadType": "application/vnd.stellaops.sca-fixture+json",
|
||||
"payload": "ew0KICAiaWQiOiAiZmM3LXRyYW5zaXRpdmUtZGVwdGgtY29uZnVzaW9uIiwNCiAgImRlc2NyaXB0aW9uIjogIlRyYW5zaXRpdmUgRGVwdGggQ29uZnVzaW9uOiBEZWVwIHRyYW5zaXRpdmUgZGVwZW5kZW5jeSByZXNvbHV0aW9uIGRpZmZlcnMgYmV0d2VlbiBwYWNrYWdlIG1hbmFnZXJzLCBjYXVzaW5nIHZlcnNpb24gbWlzbWF0Y2ggaW4gdnVsbmVyYWJpbGl0eSBhc3Nlc3NtZW50LiIsDQogICJmYWlsdXJlX21vZGUiOiB7DQogICAgImNhdGVnb3J5IjogInZlcnNpb24tbWlzbWF0Y2giLA0KICAgICJzZXZlcml0eSI6ICJoaWdoIiwNCiAgICAiaW1wYWN0IjogIkZhbHNlIG5lZ2F0aXZlcyAtIHZ1bG5lcmFibGUgdmVyc2lvbiBub3QgZGV0ZWN0ZWQgZHVlIHRvIHJlc29sdXRpb24gZGlmZmVyZW5jZXMiLA0KICAgICJyb290X2NhdXNlIjogIkRpZmZlcmVudCBkZXBlbmRlbmN5IHJlc29sdXRpb24gYWxnb3JpdGhtcyBiZXR3ZWVuIG5wbS95YXJuL3BucG0gb3IgbWF2ZW4vZ3JhZGxlIiwNCiAgICAiZGV0ZWN0aW9uX3N0cmF0ZWd5IjogIkNvbXBhcmUgcmVzb2x2ZWQgdmVyc2lvbnMgYWNyb3NzIG11bHRpcGxlIHJlc29sdXRpb24gc3RyYXRlZ2llcyINCiAgfSwNCiAgImlucHV0Ijogew0KICAgICJlY29zeXN0ZW0iOiAibWF2ZW4iLA0KICAgICJtYW5pZmVzdF9maWxlIjogInBvbS54bWwiLA0KICAgICJzY2VuYXJpbyI6ICJEaWFtb25kIGRlcGVuZGVuY3k6IEEtPkItPkRAMS4wLCBBLT5DLT5EQDIuMCwgcmVzb2x1dGlvbiBwaWNrcyBEQDEuMCB3aGljaCBpcyB2dWxuZXJhYmxlIg0KICB9LA0KICAiZXhwZWN0ZWRfZmluZGluZ3MiOiBbDQogICAgew0KICAgICAgImZpbmRpbmdfdHlwZSI6ICJ0cmFuc2l0aXZlX2RlcHRoX2NvbmZ1c2lvbiIsDQogICAgICAicGFja2FnZSI6IHsNCiAgICAgICAgIm5hbWUiOiAiY29tbW9ucy1jb2xsZWN0aW9ucyIsDQogICAgICAgICJ2ZXJzaW9uIjogIjMuMi4xIiwNCiAgICAgICAgInB1cmwiOiAicGtnOm1hdmVuL2NvbW1vbnMtY29sbGVjdGlvbnMvY29tbW9ucy1jb2xsZWN0aW9uc0AzLjIuMSINCiAgICAgIH0sDQogICAgICAiZGVwdGgiOiA0LA0KICAgICAgInJlc29sdXRpb25fcGF0aCI6IFsNCiAgICAgICAgImNvbS5leGFtcGxlOmFwcDoxLjAuMCIsDQogICAgICAgICJvcmcuc3ByaW5nZnJhbWV3b3JrOnNwcmluZy1jb3JlOjQuMy4yNSIsDQogICAgICAgICJjb21tb25zLWxvZ2dpbmc6Y29tbW9ucy1sb2dnaW5nOjEuMiIsDQogICAgICAgICJjb21tb25zLWNvbGxlY3Rpb25zOmNvbW1vbnMtY29sbGVjdGlvbnM6My4yLjEiDQogICAgICBdLA0KICAgICAgImFsdGVybmF0ZV9yZXNvbHV0aW9uIjogew0KICAgICAgICAidmVyc2lvbiI6ICIzLjIuMiIsDQogICAgICAgICJwYXRoIjogWw0KICAgICAgICAgICJjb20uZXhhbXBsZTphcHA6MS4wLjAiLA0KICAgICAgICAgICJvcmcuYXBhY2hlLnN0cnV0czpzdHJ1dHMyLWNvcmU6Mi41LjIwIiwNCiAgICAgICAgICAiY29tbW9ucy1jb2xsZWN0aW9uczpjb21tb25zLWNvbGxlY3Rpb25zOjMuMi4yIg0KICAgICAgICBdDQogICAgICB9LA0KICAgICAgInJlbGF0ZWRfY3ZlcyI6IFsiQ1ZFLTIwMTUtNjQyMCJdLA0KICAgICAgInJlY29tbWVuZGF0aW9uIjogIkV4cGxpY2l0bHkgZGVjbGFyZSBjb21tb25zLWNvbGxlY3Rpb25zOjMuMi4yIGluIGRlcGVuZGVuY3lNYW5hZ2VtZW50IHRvIG92ZXJyaWRlIHRyYW5zaXRpdmUgcmVzb2x1dGlvbiINCiAgICB9DQogIF0sDQogICJ0ZXN0X3ZlY3RvcnMiOiB7DQogICAgImRpYW1vbmRfcm9vdCI6ICJjb20uZXhhbXBsZTphcHA6MS4wLjAiLA0KICAgICJsZWZ0X2JyYW5jaCI6ICJzcHJpbmctY29yZSAtPiBjb21tb25zLWxvZ2dpbmcgLT4gY29tbW9ucy1jb2xsZWN0aW9uczozLjIuMSIsDQogICAgInJpZ2h0X2JyYW5jaCI6ICJzdHJ1dHMyLWNvcmUgLT4gY29tbW9ucy1jb2xsZWN0aW9uczozLjIuMiIsDQogICAgIm1hdmVuX3Jlc29sdXRpb24iOiAiMy4yLjEgKG5lYXJlc3Qtd2lucykiLA0KICAgICJncmFkbGVfcmVzb2x1dGlvbiI6ICIzLjIuMiAoaGlnaGVzdC13aW5zKSIsDQogICAgImV4cGVjdGVkX3NjYW5uZXJfYmVoYXZpb3IiOiAiRGV0ZWN0IHZlcnNpb24gYW1iaWd1aXR5IGFuZCBmbGFnIHBvdGVudGlhbCBDVkUtMjAxNS02NDIwIGV4cG9zdXJlIg0KICB9DQp9DQo=",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "stellaops:sca-catalogue:v1",
|
||||
"sig": "fixture-signature-placeholder"
|
||||
}
|
||||
]
|
||||
}
|
||||
64
tests/fixtures/sca/catalogue/fc8/Dockerfile.multistage
vendored
Normal file
64
tests/fixtures/sca/catalogue/fc8/Dockerfile.multistage
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
# FC8 - Multi-Stage Leakage Example Dockerfile
|
||||
# This Dockerfile demonstrates the leakage anti-pattern
|
||||
|
||||
# ============================================
|
||||
# BUILDER STAGE - installs ALL dependencies
|
||||
# ============================================
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package.json package-lock.json ./
|
||||
|
||||
# Install ALL dependencies (including devDependencies)
|
||||
RUN npm ci
|
||||
|
||||
# Copy source code
|
||||
COPY src/ ./src/
|
||||
COPY tsconfig.json ./
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# ============================================
|
||||
# RUNTIME STAGE - PROBLEMATIC PATTERN
|
||||
# ============================================
|
||||
FROM node:18-alpine AS runtime
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy built artifacts
|
||||
COPY --from=builder /app/dist ./dist
|
||||
|
||||
# PROBLEM: This copies ALL node_modules including devDependencies!
|
||||
# typescript, jest, eslint, @types/* are all included unnecessarily
|
||||
COPY --from=builder /app/node_modules ./node_modules
|
||||
|
||||
# Copy package.json for runtime metadata
|
||||
COPY package.json ./
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3000
|
||||
|
||||
# Start application
|
||||
CMD ["node", "dist/index.js"]
|
||||
|
||||
# ============================================
|
||||
# CORRECT PATTERN (commented out for reference)
|
||||
# ============================================
|
||||
# FROM node:18-alpine AS runtime-correct
|
||||
#
|
||||
# WORKDIR /app
|
||||
#
|
||||
# # Copy package files first
|
||||
# COPY package.json package-lock.json ./
|
||||
#
|
||||
# # Install ONLY production dependencies
|
||||
# RUN npm ci --only=production
|
||||
#
|
||||
# # Copy built artifacts
|
||||
# COPY --from=builder /app/dist ./dist
|
||||
#
|
||||
# EXPOSE 3000
|
||||
# CMD ["node", "dist/index.js"]
|
||||
54
tests/fixtures/sca/catalogue/fc8/expected.json
vendored
Normal file
54
tests/fixtures/sca/catalogue/fc8/expected.json
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"id": "fc8-multi-stage-leakage",
|
||||
"description": "Multi-Stage Leakage: Build-time dependencies, tools, or secrets leak into the final runtime container image through improper COPY commands in multi-stage Dockerfiles.",
|
||||
"failure_mode": {
|
||||
"category": "build-artifact-leakage",
|
||||
"severity": "critical",
|
||||
"impact": "Enlarged attack surface - dev tools, build secrets, and unnecessary packages in production image",
|
||||
"root_cause": "COPY --from=builder copies entire directories including dev dependencies",
|
||||
"detection_strategy": "Compare build-stage vs runtime-stage dependency sets, flag unexpected packages in final image"
|
||||
},
|
||||
"input": {
|
||||
"ecosystem": "docker",
|
||||
"manifest_file": "Dockerfile.multistage",
|
||||
"scenario": "Multi-stage build copies node_modules from builder stage, including devDependencies"
|
||||
},
|
||||
"expected_findings": [
|
||||
{
|
||||
"finding_type": "multi_stage_leakage",
|
||||
"leaked_packages": [
|
||||
{
|
||||
"name": "typescript",
|
||||
"version": "4.9.5",
|
||||
"purl": "pkg:npm/typescript@4.9.5",
|
||||
"stage": "builder",
|
||||
"should_be_in_runtime": false
|
||||
},
|
||||
{
|
||||
"name": "jest",
|
||||
"version": "29.5.0",
|
||||
"purl": "pkg:npm/jest@29.5.0",
|
||||
"stage": "builder",
|
||||
"should_be_in_runtime": false
|
||||
},
|
||||
{
|
||||
"name": "eslint",
|
||||
"version": "8.36.0",
|
||||
"purl": "pkg:npm/eslint@8.36.0",
|
||||
"stage": "builder",
|
||||
"should_be_in_runtime": false
|
||||
}
|
||||
],
|
||||
"copy_command": "COPY --from=builder /app/node_modules ./node_modules",
|
||||
"recommendation": "Use npm ci --only=production in runtime stage or selectively copy only production dependencies"
|
||||
}
|
||||
],
|
||||
"test_vectors": {
|
||||
"builder_stage_packages": 245,
|
||||
"expected_runtime_packages": 89,
|
||||
"actual_runtime_packages": 245,
|
||||
"leaked_dev_packages": 156,
|
||||
"image_size_increase": "340MB",
|
||||
"expected_scanner_behavior": "Detect devDependencies in production image layer, calculate bloat metrics"
|
||||
}
|
||||
}
|
||||
50
tests/fixtures/sca/catalogue/fc8/input.txt
vendored
Normal file
50
tests/fixtures/sca/catalogue/fc8/input.txt
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
# FC8 - Multi-Stage Leakage Test Input
|
||||
# Scenario: Build-time dependencies leak into runtime image
|
||||
|
||||
== Dockerfile.multistage ==
|
||||
# See Dockerfile.multistage in this directory
|
||||
|
||||
== package.json ==
|
||||
{
|
||||
"name": "fc8-leaky-app",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^4.9.5",
|
||||
"jest": "^29.5.0",
|
||||
"eslint": "^8.36.0",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/node": "^18.15.0"
|
||||
}
|
||||
}
|
||||
|
||||
== Expected Build Behavior ==
|
||||
Builder stage:
|
||||
- npm install (installs ALL dependencies including dev)
|
||||
- npm run build (compiles TypeScript)
|
||||
- node_modules contains 245 packages
|
||||
|
||||
Runtime stage (PROBLEMATIC):
|
||||
- COPY --from=builder /app/node_modules ./node_modules
|
||||
- Copies ALL 245 packages including devDependencies
|
||||
- Final image contains typescript, jest, eslint (unnecessary)
|
||||
|
||||
Runtime stage (CORRECT):
|
||||
- npm ci --only=production
|
||||
- Would only install 89 production packages
|
||||
- No dev tools in final image
|
||||
|
||||
== Vulnerability Impact ==
|
||||
Leaked packages may have their own vulnerabilities:
|
||||
- typescript@4.9.5: No known CVEs but unnecessary attack surface
|
||||
- jest@29.5.0: Test framework with file system access
|
||||
- eslint@8.36.0: Linter that can execute arbitrary rules
|
||||
|
||||
== Expected Scanner Behavior ==
|
||||
- Analyze multi-stage Dockerfile
|
||||
- Track package flow between stages
|
||||
- Identify packages that should NOT be in runtime
|
||||
- Report leakage with remediation guidance
|
||||
10
tests/fixtures/sca/catalogue/fc8/manifest.dsse.json
vendored
Normal file
10
tests/fixtures/sca/catalogue/fc8/manifest.dsse.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"payloadType": "application/vnd.stellaops.sca-fixture+json",
|
||||
"payload": "ew0KICAiaWQiOiAiZmM4LW11bHRpLXN0YWdlLWxlYWthZ2UiLA0KICAiZGVzY3JpcHRpb24iOiAiTXVsdGktU3RhZ2UgTGVha2FnZTogQnVpbGQtdGltZSBkZXBlbmRlbmNpZXMsIHRvb2xzLCBvciBzZWNyZXRzIGxlYWsgaW50byB0aGUgZmluYWwgcnVudGltZSBjb250YWluZXIgaW1hZ2UgdGhyb3VnaCBpbXByb3BlciBDT1BZIGNvbW1hbmRzIGluIG11bHRpLXN0YWdlIERvY2tlcmZpbGVzLiIsDQogICJmYWlsdXJlX21vZGUiOiB7DQogICAgImNhdGVnb3J5IjogImJ1aWxkLWFydGlmYWN0LWxlYWthZ2UiLA0KICAgICJzZXZlcml0eSI6ICJjcml0aWNhbCIsDQogICAgImltcGFjdCI6ICJFbmxhcmdlZCBhdHRhY2sgc3VyZmFjZSAtIGRldiB0b29scywgYnVpbGQgc2VjcmV0cywgYW5kIHVubmVjZXNzYXJ5IHBhY2thZ2VzIGluIHByb2R1Y3Rpb24gaW1hZ2UiLA0KICAgICJyb290X2NhdXNlIjogIkNPUFkgLS1mcm9tPWJ1aWxkZXIgY29waWVzIGVudGlyZSBkaXJlY3RvcmllcyBpbmNsdWRpbmcgZGV2IGRlcGVuZGVuY2llcyIsDQogICAgImRldGVjdGlvbl9zdHJhdGVneSI6ICJDb21wYXJlIGJ1aWxkLXN0YWdlIHZzIHJ1bnRpbWUtc3RhZ2UgZGVwZW5kZW5jeSBzZXRzLCBmbGFnIHVuZXhwZWN0ZWQgcGFja2FnZXMgaW4gZmluYWwgaW1hZ2UiDQogIH0sDQogICJpbnB1dCI6IHsNCiAgICAiZWNvc3lzdGVtIjogImRvY2tlciIsDQogICAgIm1hbmlmZXN0X2ZpbGUiOiAiRG9ja2VyZmlsZS5tdWx0aXN0YWdlIiwNCiAgICAic2NlbmFyaW8iOiAiTXVsdGktc3RhZ2UgYnVpbGQgY29waWVzIG5vZGVfbW9kdWxlcyBmcm9tIGJ1aWxkZXIgc3RhZ2UsIGluY2x1ZGluZyBkZXZEZXBlbmRlbmNpZXMiDQogIH0sDQogICJleHBlY3RlZF9maW5kaW5ncyI6IFsNCiAgICB7DQogICAgICAiZmluZGluZ190eXBlIjogIm11bHRpX3N0YWdlX2xlYWthZ2UiLA0KICAgICAgImxlYWtlZF9wYWNrYWdlcyI6IFsNCiAgICAgICAgew0KICAgICAgICAgICJuYW1lIjogInR5cGVzY3JpcHQiLA0KICAgICAgICAgICJ2ZXJzaW9uIjogIjQuOS41IiwNCiAgICAgICAgICAicHVybCI6ICJwa2c6bnBtL3R5cGVzY3JpcHRANC45LjUiLA0KICAgICAgICAgICJzdGFnZSI6ICJidWlsZGVyIiwNCiAgICAgICAgICAic2hvdWxkX2JlX2luX3J1bnRpbWUiOiBmYWxzZQ0KICAgICAgICB9LA0KICAgICAgICB7DQogICAgICAgICAgIm5hbWUiOiAiamVzdCIsDQogICAgICAgICAgInZlcnNpb24iOiAiMjkuNS4wIiwNCiAgICAgICAgICAicHVybCI6ICJwa2c6bnBtL2plc3RAMjkuNS4wIiwNCiAgICAgICAgICAic3RhZ2UiOiAiYnVpbGRlciIsDQogICAgICAgICAgInNob3VsZF9iZV9pbl9ydW50aW1lIjogZmFsc2UNCiAgICAgICAgfSwNCiAgICAgICAgew0KICAgICAgICAgICJuYW1lIjogImVzbGludCIsDQogICAgICAgICAgInZlcnNpb24iOiAiOC4zNi4wIiwNCiAgICAgICAgICAicHVybCI6ICJwa2c6bnBtL2VzbGludEA4LjM2LjAiLA0KICAgICAgICAgICJzdGFnZSI6ICJidWlsZGVyIiwNCiAgICAgICAgICAic2hvdWxkX2JlX2luX3J1bnRpbWUiOiBmYWxzZQ0KICAgICAgICB9DQogICAgICBdLA0KICAgICAgImNvcHlfY29tbWFuZCI6ICJDT1BZIC0tZnJvbT1idWlsZGVyIC9hcHAvbm9kZV9tb2R1bGVzIC4vbm9kZV9tb2R1bGVzIiwNCiAgICAgICJyZWNvbW1lbmRhdGlvbiI6ICJVc2UgbnBtIGNpIC0tb25seT1wcm9kdWN0aW9uIGluIHJ1bnRpbWUgc3RhZ2Ugb3Igc2VsZWN0aXZlbHkgY29weSBvbmx5IHByb2R1Y3Rpb24gZGVwZW5kZW5jaWVzIg0KICAgIH0NCiAgXSwNCiAgInRlc3RfdmVjdG9ycyI6IHsNCiAgICAiYnVpbGRlcl9zdGFnZV9wYWNrYWdlcyI6IDI0NSwNCiAgICAiZXhwZWN0ZWRfcnVudGltZV9wYWNrYWdlcyI6IDg5LA0KICAgICJhY3R1YWxfcnVudGltZV9wYWNrYWdlcyI6IDI0NSwNCiAgICAibGVha2VkX2Rldl9wYWNrYWdlcyI6IDE1NiwNCiAgICAiaW1hZ2Vfc2l6ZV9pbmNyZWFzZSI6ICIzNDBNQiIsDQogICAgImV4cGVjdGVkX3NjYW5uZXJfYmVoYXZpb3IiOiAiRGV0ZWN0IGRldkRlcGVuZGVuY2llcyBpbiBwcm9kdWN0aW9uIGltYWdlIGxheWVyLCBjYWxjdWxhdGUgYmxvYXQgbWV0cmljcyINCiAgfQ0KfQ0K",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "stellaops:sca-catalogue:v1",
|
||||
"sig": "fixture-signature-placeholder"
|
||||
}
|
||||
]
|
||||
}
|
||||
45
tests/fixtures/sca/catalogue/fc9/expected.json
vendored
Normal file
45
tests/fixtures/sca/catalogue/fc9/expected.json
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"id": "fc9-purl-namespace-collision",
|
||||
"description": "PURL Namespace Collision: Same package name exists in multiple ecosystems (npm, pypi, maven) with different vulnerabilities. Scanner may misattribute CVEs across ecosystems.",
|
||||
"failure_mode": {
|
||||
"category": "ecosystem-confusion",
|
||||
"severity": "high",
|
||||
"impact": "False positives/negatives due to CVE misattribution between ecosystems",
|
||||
"root_cause": "Package name alone is insufficient - ecosystem context required for accurate matching",
|
||||
"detection_strategy": "Always include ecosystem in PURL, cross-reference with lockfile ecosystem markers"
|
||||
},
|
||||
"input": {
|
||||
"ecosystems": ["npm", "pypi"],
|
||||
"package_name": "requests",
|
||||
"scenario": "Package 'requests' exists in both npm and pypi with completely different codebases and vulnerabilities"
|
||||
},
|
||||
"expected_findings": [
|
||||
{
|
||||
"finding_type": "purl_namespace_collision",
|
||||
"collision_group": [
|
||||
{
|
||||
"ecosystem": "npm",
|
||||
"purl": "pkg:npm/requests@2.0.0",
|
||||
"description": "Simplified HTTP request client for Node.js",
|
||||
"vulnerabilities": [],
|
||||
"status": "deprecated"
|
||||
},
|
||||
{
|
||||
"ecosystem": "pypi",
|
||||
"purl": "pkg:pypi/requests@2.28.0",
|
||||
"description": "Python HTTP library",
|
||||
"vulnerabilities": ["CVE-2023-32681"],
|
||||
"status": "active"
|
||||
}
|
||||
],
|
||||
"risk": "Scanners without proper ecosystem context may apply Python CVEs to Node.js package or vice versa",
|
||||
"recommendation": "Always use fully-qualified PURLs with ecosystem prefix, validate ecosystem from lockfile"
|
||||
}
|
||||
],
|
||||
"test_vectors": {
|
||||
"npm_requests_purl": "pkg:npm/requests@2.0.0",
|
||||
"pypi_requests_purl": "pkg:pypi/requests@2.28.0",
|
||||
"common_confusion": "CVE-2023-32681 is for pypi/requests, not npm/requests",
|
||||
"expected_scanner_behavior": "Detect collision, ensure CVEs are ecosystem-specific, warn on ambiguous references"
|
||||
}
|
||||
}
|
||||
59
tests/fixtures/sca/catalogue/fc9/input.txt
vendored
Normal file
59
tests/fixtures/sca/catalogue/fc9/input.txt
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
# FC9 - PURL Namespace Collision Test Input
|
||||
# Scenario: Package "requests" exists in multiple ecosystems
|
||||
|
||||
== Project Structure ==
|
||||
A polyglot application with both Node.js and Python components:
|
||||
|
||||
/frontend (Node.js)
|
||||
package.json
|
||||
package-lock.json
|
||||
|
||||
/backend (Python)
|
||||
requirements.txt
|
||||
poetry.lock
|
||||
|
||||
== package.json (Node.js) ==
|
||||
{
|
||||
"name": "fc9-frontend",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"requests": "2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
== requirements.txt (Python) ==
|
||||
requests==2.28.0
|
||||
flask==2.3.0
|
||||
|
||||
== Package Comparison ==
|
||||
|
||||
npm/requests@2.0.0:
|
||||
- Author: Mikeal Rogers
|
||||
- Description: Simplified HTTP request client
|
||||
- Status: DEPRECATED since 2020
|
||||
- Known CVEs: None
|
||||
- Last publish: 2014
|
||||
|
||||
pypi/requests@2.28.0:
|
||||
- Author: Kenneth Reitz / PSF
|
||||
- Description: Python HTTP for Humans
|
||||
- Status: ACTIVE, widely used
|
||||
- Known CVEs: CVE-2023-32681 (proxy auth leak)
|
||||
- Downloads: 100M+/month
|
||||
|
||||
== Collision Scenario ==
|
||||
|
||||
If scanner sees "requests@2.28.0" without ecosystem context:
|
||||
- Could incorrectly apply CVE-2023-32681 to Node.js component
|
||||
- Could miss the deprecation warning for npm/requests
|
||||
|
||||
Correct identification requires:
|
||||
- npm ecosystem -> pkg:npm/requests@2.0.0 (no CVEs, deprecated)
|
||||
- pypi ecosystem -> pkg:pypi/requests@2.28.0 (CVE-2023-32681)
|
||||
|
||||
== Expected Scanner Behavior ==
|
||||
- Parse lockfiles to determine ecosystem context
|
||||
- Generate fully-qualified PURLs with ecosystem
|
||||
- Match CVEs only to correct ecosystem
|
||||
- Flag namespace collision as informational finding
|
||||
- Warn about npm/requests deprecation
|
||||
10
tests/fixtures/sca/catalogue/fc9/manifest.dsse.json
vendored
Normal file
10
tests/fixtures/sca/catalogue/fc9/manifest.dsse.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"payloadType": "application/vnd.stellaops.sca-fixture+json",
|
||||
"payload": "ew0KICAiaWQiOiAiZmM5LXB1cmwtbmFtZXNwYWNlLWNvbGxpc2lvbiIsDQogICJkZXNjcmlwdGlvbiI6ICJQVVJMIE5hbWVzcGFjZSBDb2xsaXNpb246IFNhbWUgcGFja2FnZSBuYW1lIGV4aXN0cyBpbiBtdWx0aXBsZSBlY29zeXN0ZW1zIChucG0sIHB5cGksIG1hdmVuKSB3aXRoIGRpZmZlcmVudCB2dWxuZXJhYmlsaXRpZXMuIFNjYW5uZXIgbWF5IG1pc2F0dHJpYnV0ZSBDVkVzIGFjcm9zcyBlY29zeXN0ZW1zLiIsDQogICJmYWlsdXJlX21vZGUiOiB7DQogICAgImNhdGVnb3J5IjogImVjb3N5c3RlbS1jb25mdXNpb24iLA0KICAgICJzZXZlcml0eSI6ICJoaWdoIiwNCiAgICAiaW1wYWN0IjogIkZhbHNlIHBvc2l0aXZlcy9uZWdhdGl2ZXMgZHVlIHRvIENWRSBtaXNhdHRyaWJ1dGlvbiBiZXR3ZWVuIGVjb3N5c3RlbXMiLA0KICAgICJyb290X2NhdXNlIjogIlBhY2thZ2UgbmFtZSBhbG9uZSBpcyBpbnN1ZmZpY2llbnQgLSBlY29zeXN0ZW0gY29udGV4dCByZXF1aXJlZCBmb3IgYWNjdXJhdGUgbWF0Y2hpbmciLA0KICAgICJkZXRlY3Rpb25fc3RyYXRlZ3kiOiAiQWx3YXlzIGluY2x1ZGUgZWNvc3lzdGVtIGluIFBVUkwsIGNyb3NzLXJlZmVyZW5jZSB3aXRoIGxvY2tmaWxlIGVjb3N5c3RlbSBtYXJrZXJzIg0KICB9LA0KICAiaW5wdXQiOiB7DQogICAgImVjb3N5c3RlbXMiOiBbIm5wbSIsICJweXBpIl0sDQogICAgInBhY2thZ2VfbmFtZSI6ICJyZXF1ZXN0cyIsDQogICAgInNjZW5hcmlvIjogIlBhY2thZ2UgJ3JlcXVlc3RzJyBleGlzdHMgaW4gYm90aCBucG0gYW5kIHB5cGkgd2l0aCBjb21wbGV0ZWx5IGRpZmZlcmVudCBjb2RlYmFzZXMgYW5kIHZ1bG5lcmFiaWxpdGllcyINCiAgfSwNCiAgImV4cGVjdGVkX2ZpbmRpbmdzIjogWw0KICAgIHsNCiAgICAgICJmaW5kaW5nX3R5cGUiOiAicHVybF9uYW1lc3BhY2VfY29sbGlzaW9uIiwNCiAgICAgICJjb2xsaXNpb25fZ3JvdXAiOiBbDQogICAgICAgIHsNCiAgICAgICAgICAiZWNvc3lzdGVtIjogIm5wbSIsDQogICAgICAgICAgInB1cmwiOiAicGtnOm5wbS9yZXF1ZXN0c0AyLjAuMCIsDQogICAgICAgICAgImRlc2NyaXB0aW9uIjogIlNpbXBsaWZpZWQgSFRUUCByZXF1ZXN0IGNsaWVudCBmb3IgTm9kZS5qcyIsDQogICAgICAgICAgInZ1bG5lcmFiaWxpdGllcyI6IFtdLA0KICAgICAgICAgICJzdGF0dXMiOiAiZGVwcmVjYXRlZCINCiAgICAgICAgfSwNCiAgICAgICAgew0KICAgICAgICAgICJlY29zeXN0ZW0iOiAicHlwaSIsDQogICAgICAgICAgInB1cmwiOiAicGtnOnB5cGkvcmVxdWVzdHNAMi4yOC4wIiwNCiAgICAgICAgICAiZGVzY3JpcHRpb24iOiAiUHl0aG9uIEhUVFAgbGlicmFyeSIsDQogICAgICAgICAgInZ1bG5lcmFiaWxpdGllcyI6IFsiQ1ZFLTIwMjMtMzI2ODEiXSwNCiAgICAgICAgICAic3RhdHVzIjogImFjdGl2ZSINCiAgICAgICAgfQ0KICAgICAgXSwNCiAgICAgICJyaXNrIjogIlNjYW5uZXJzIHdpdGhvdXQgcHJvcGVyIGVjb3N5c3RlbSBjb250ZXh0IG1heSBhcHBseSBQeXRob24gQ1ZFcyB0byBOb2RlLmpzIHBhY2thZ2Ugb3IgdmljZSB2ZXJzYSIsDQogICAgICAicmVjb21tZW5kYXRpb24iOiAiQWx3YXlzIHVzZSBmdWxseS1xdWFsaWZpZWQgUFVSTHMgd2l0aCBlY29zeXN0ZW0gcHJlZml4LCB2YWxpZGF0ZSBlY29zeXN0ZW0gZnJvbSBsb2NrZmlsZSINCiAgICB9DQogIF0sDQogICJ0ZXN0X3ZlY3RvcnMiOiB7DQogICAgIm5wbV9yZXF1ZXN0c19wdXJsIjogInBrZzpucG0vcmVxdWVzdHNAMi4wLjAiLA0KICAgICJweXBpX3JlcXVlc3RzX3B1cmwiOiAicGtnOnB5cGkvcmVxdWVzdHNAMi4yOC4wIiwNCiAgICAiY29tbW9uX2NvbmZ1c2lvbiI6ICJDVkUtMjAyMy0zMjY4MSBpcyBmb3IgcHlwaS9yZXF1ZXN0cywgbm90IG5wbS9yZXF1ZXN0cyIsDQogICAgImV4cGVjdGVkX3NjYW5uZXJfYmVoYXZpb3IiOiAiRGV0ZWN0IGNvbGxpc2lvbiwgZW5zdXJlIENWRXMgYXJlIGVjb3N5c3RlbS1zcGVjaWZpYywgd2FybiBvbiBhbWJpZ3VvdXMgcmVmZXJlbmNlcyINCiAgfQ0KfQ0K",
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "stellaops:sca-catalogue:v1",
|
||||
"sig": "fixture-signature-placeholder"
|
||||
}
|
||||
]
|
||||
}
|
||||
40
tests/fixtures/sca/catalogue/inputs.lock
vendored
Normal file
40
tests/fixtures/sca/catalogue/inputs.lock
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
# SCA Failure Catalogue Inputs Lock
|
||||
# Generated: 2026-01-29
|
||||
# Version: 1.0.0
|
||||
#
|
||||
# This file locks the input specifications for FC6-FC10 failure catalogue fixtures.
|
||||
# Each fixture demonstrates a specific SCA (Software Composition Analysis) failure mode.
|
||||
#
|
||||
# Fixture Index:
|
||||
# FC6 - Phantom Dependency: Declared but not installed dependency
|
||||
# FC7 - Transitive Depth Confusion: Deep transitive resolution mismatch
|
||||
# FC8 - Multi-Stage Leakage: Build artifacts leak to runtime image
|
||||
# FC9 - PURL Namespace Collision: Same name in different ecosystems
|
||||
# FC10 - CVE Split/Merge/Chain: Complex CVE relationship handling
|
||||
#
|
||||
# Hash: sha256:fc6fc7fc8fc9fc10-catalogue-v1
|
||||
|
||||
fc6:
|
||||
type: phantom-dependency
|
||||
ecosystem: npm
|
||||
trigger: package.json declares unused dependency
|
||||
|
||||
fc7:
|
||||
type: transitive-depth-confusion
|
||||
ecosystem: maven
|
||||
trigger: diamond dependency with version conflict at depth 4
|
||||
|
||||
fc8:
|
||||
type: multi-stage-leakage
|
||||
ecosystem: docker
|
||||
trigger: COPY --from=builder includes dev dependencies
|
||||
|
||||
fc9:
|
||||
type: purl-namespace-collision
|
||||
ecosystems: [npm, pypi]
|
||||
trigger: package "requests" exists in both with different vulns
|
||||
|
||||
fc10:
|
||||
type: cve-split-merge-chain
|
||||
ecosystem: java
|
||||
trigger: Log4Shell CVE split and related chain
|
||||
Reference in New Issue
Block a user