Skip to content

Commit ad0a05c

Browse files
authored
Merge branch '196-csaf-2.1' into feat/199-Informative-Tests_CSAF2_1_6.3.4
2 parents 1147c5c + 6ca48b7 commit ad0a05c

File tree

4 files changed

+141
-3
lines changed

4 files changed

+141
-3
lines changed

csaf_2_1/informativeTests.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
export {
2-
informativeTest_6_3_1,
32
informativeTest_6_3_2,
43
informativeTest_6_3_3,
54
informativeTest_6_3_5,
@@ -10,4 +9,5 @@ export {
109
informativeTest_6_3_10,
1110
informativeTest_6_3_11,
1211
} from '../informativeTests.js'
13-
export { informativeTest_6_3_4 } from './informativeTests/informativeTest_6_3_4.js'
12+
export { informativeTest_6_3_1 } from './informativeTests/informativeTest_6_3_1.js'
13+
export { informativeTest_6_3_4 } from './informativeTests/informativeTest_6_3_4.js'
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import Ajv from 'ajv/dist/jtd.js'
2+
3+
const ajv = new Ajv()
4+
5+
/**
6+
* @typedef {object} MetricContent
7+
* @property {object} [cvss_v2]
8+
* @property {string} cvss_v2.version
9+
* @property {object} [cvss_v3]
10+
* @property {string} cvss_v3.version
11+
* @property {object} [cvss_v4]
12+
* @property {string} cvss_v4.version
13+
*/
14+
15+
/**
16+
* @typedef {object} Metric
17+
* @property {MetricContent} [content]
18+
* @property {Array<string>} products
19+
*/
20+
21+
const inputSchema = /** @type {const} */ ({
22+
additionalProperties: true,
23+
properties: {
24+
vulnerabilities: {
25+
elements: {
26+
additionalProperties: true,
27+
properties: {},
28+
optionalProperties: {
29+
metrics: {
30+
elements: {
31+
additionalProperties: true,
32+
properties: {
33+
products: {
34+
elements: { type: 'string' },
35+
},
36+
},
37+
optionalProperties: {
38+
content: {
39+
additionalProperties: true,
40+
optionalProperties: {
41+
cvss_v2: {
42+
additionalProperties: true,
43+
properties: {
44+
version: { type: 'string' },
45+
},
46+
},
47+
cvss_v3: {
48+
additionalProperties: true,
49+
properties: {
50+
version: { type: 'string' },
51+
},
52+
},
53+
cvss_v4: {
54+
additionalProperties: true,
55+
properties: {
56+
version: { type: 'string' },
57+
},
58+
},
59+
},
60+
},
61+
},
62+
},
63+
},
64+
},
65+
},
66+
},
67+
},
68+
})
69+
70+
const validateInput = ajv.compile(inputSchema)
71+
72+
/**
73+
* @param {unknown} doc
74+
* @returns
75+
*/
76+
export function informativeTest_6_3_1(doc) {
77+
const ctx = {
78+
infos: /** @type {Array<{ message: string; instancePath: string }>} */ ([]),
79+
}
80+
81+
if (!validateInput(doc)) {
82+
return ctx
83+
}
84+
85+
/**
86+
* @param {Metric} metric
87+
* @param {Set<string>} versionSet
88+
*/
89+
function addVersionsInMetricToSet(metric, versionSet) {
90+
if (metric.content?.cvss_v2?.version !== undefined) {
91+
versionSet.add(metric.content.cvss_v2.version)
92+
}
93+
if (metric.content?.cvss_v3?.version !== undefined) {
94+
versionSet.add(metric.content.cvss_v3.version)
95+
}
96+
if (metric.content?.cvss_v4?.version !== undefined) {
97+
versionSet.add(metric.content.cvss_v4.version)
98+
}
99+
}
100+
101+
const vulnerabilities = doc.vulnerabilities
102+
103+
vulnerabilities.forEach((vulnerability, vulnerabilityIndex) => {
104+
/** @type {Map<string, Set<string>>} */
105+
const cvssVersionsByProduct = new Map()
106+
const metricIndexByProduct = new Map()
107+
/** @type {Array<Metric> | undefined} */
108+
const metrics = vulnerability.metrics
109+
metrics?.forEach((metric, metricIndex) => {
110+
/** @type {Array<string>} */
111+
const products = metric.products
112+
products.forEach((product) => {
113+
const versionSet = cvssVersionsByProduct.get(product) ?? new Set()
114+
cvssVersionsByProduct.set(product, versionSet)
115+
metricIndexByProduct.set(product, metricIndex)
116+
addVersionsInMetricToSet(metric, versionSet)
117+
})
118+
})
119+
cvssVersionsByProduct.forEach((value, product) => {
120+
if (value.size === 1 && value.values().next().value === '2.0') {
121+
const metricIndex = metricIndexByProduct.get(product)
122+
ctx.infos.push({
123+
instancePath: `/vulnerabilities/${vulnerabilityIndex}/metrics/${metricIndex}`,
124+
message: `use of cvss v2 as the only scoring system for product ${product}`,
125+
})
126+
}
127+
})
128+
})
129+
130+
return ctx
131+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import assert from 'node:assert'
2+
import { informativeTest_6_3_1 } from '../../csaf_2_1/informativeTests.js'
3+
4+
describe('informativeTest_6_3_1', function () {
5+
it('only runs on relevant documents', function () {
6+
assert.equal(informativeTest_6_3_1({ document: 'mydoc' }).infos.length, 0)
7+
})
8+
})

tests/csaf_2_1/oasis.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ const excluded = [
5959
'6.2.39.1',
6060
'6.2.39.2',
6161
'6.2.40',
62-
'6.3.1',
6362
'6.3.2',
6463
'6.3.14',
6564
'6.3.15',

0 commit comments

Comments
 (0)