-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Expand file tree
/
Copy pathvulnerabilities.mjs
More file actions
85 lines (67 loc) · 2.59 KB
/
vulnerabilities.mjs
File metadata and controls
85 lines (67 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { VULNERABILITIES_URL } from '#site/next.constants.mjs';
import { fetchWithRetry } from '#site/util/fetch';
const RANGE_REGEX = /([<>]=?)\s*(\d+)(?:\.(\d+))?/;
const V0_REGEX = /^0\.\d+(\.x)?$/;
const VER_REGEX = /^\d+\.x$/;
/**
* Fetches vulnerability data from the Node.js Security Working Group repository,
* and returns it grouped by major version.
*
* @returns {Promise<import('#site/types/vulnerabilities').GroupedVulnerabilities>} Grouped vulnerabilities
*/
export default () =>
fetchWithRetry(VULNERABILITIES_URL)
.then(response => response.json())
.then(payload => {
/** @type {Array<import('#site/types/vulnerabilities').RawVulnerability>} */
const data = Object.values(payload);
/** @type {Promise<import('#site/types/vulnerabilities').GroupedVulnerabilities> */
const grouped = {};
// Helper function to add vulnerability to a major version group
const addToGroup = (majorVersion, vulnerability) => {
grouped[majorVersion] ??= [];
grouped[majorVersion].push(vulnerability);
};
// Helper function to process version patterns
const processVersion = (version, vulnerability) => {
// Handle 0.X versions (pre-semver)
if (V0_REGEX.test(version)) {
addToGroup('0', vulnerability);
return;
}
// Handle simple major.x patterns (e.g., 12.x)
if (VER_REGEX.test(version)) {
const majorVersion = version.split('.')[0];
addToGroup(majorVersion, vulnerability);
return;
}
// Handle version ranges (>, >=, <, <=)
const rangeMatch = RANGE_REGEX.exec(version);
if (rangeMatch) {
const [, operator, majorVersion] = rangeMatch;
const majorNum = parseInt(majorVersion, 10);
switch (operator) {
case '>=':
case '>':
case '<=':
addToGroup(majorVersion, vulnerability);
break;
case '<':
// Add to all major versions below the specified version
for (let i = majorNum - 1; i >= 0; i--) {
addToGroup(i.toString(), vulnerability);
}
break;
}
}
};
for (const { ref, ...vulnerability } of Object.values(data)) {
vulnerability.url = ref;
// Process all potential versions from the vulnerable field
const versions = vulnerability.vulnerable.split(' || ').filter(Boolean);
for (const version of versions) {
processVersion(version, vulnerability);
}
}
return grouped;
});