retire 5.2.8 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/lib/cli.js +2 -2
- package/lib/repo.js +1 -0
- package/lib/reporters/cyclonedx-1_6-json.js +51 -1
- package/lib/reporting.js +1 -0
- package/lib/retire.js +4 -1
- package/lib/types.d.ts +1 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [5.4.0]
|
|
4
|
+
|
|
5
|
+
### Improvements
|
|
6
|
+
|
|
7
|
+
- Add possibility to exclude specific versions for a vulnerability (example: jquery-1.12.4-aem which has some extra patches).
|
|
8
|
+
|
|
9
|
+
## [5.3.0]
|
|
10
|
+
|
|
11
|
+
### Improvement
|
|
12
|
+
|
|
13
|
+
- Add cyclonedxJSON1_6_VEX as output format for CycloneDX 1.6 with vulnerability information
|
|
14
|
+
|
|
3
15
|
## [5.2.8]
|
|
4
16
|
|
|
5
17
|
### Bugfix
|
package/lib/cli.js
CHANGED
|
@@ -70,7 +70,7 @@ const prg = commander_1.program
|
|
|
70
70
|
.option('--jsrepo <path|url>', "Local or internal version of repo. Can be multiple comma separated. Default: 'central')")
|
|
71
71
|
.option('--cachedir <path>', 'Path to use for local cache instead of /tmp/.retire-cache')
|
|
72
72
|
.option('--proxy <url>', 'Proxy url (http://some.host:8080)')
|
|
73
|
-
.option('--outputformat <format>', 'Valid formats: text, json, jsonsimple, depcheck (experimental), cyclonedx, cyclonedxJSON
|
|
73
|
+
.option('--outputformat <format>', 'Valid formats: text, json, jsonsimple, depcheck (experimental), cyclonedx, cyclonedxJSON, cyclonedxJSON1_6, cyclonedxJSON1_6_VEX')
|
|
74
74
|
.option('--outputpath <path>', 'File to which output should be written')
|
|
75
75
|
.option('--ignore <paths>', 'Comma delimited list of paths to ignore')
|
|
76
76
|
.option('--ignorefile <path>', 'Custom ignore file, defaults to .retireignore / .retireignore.json')
|
|
@@ -88,7 +88,7 @@ const colorwarn = prg.colors ? ansi_colors_1.default.red : (x) => x;
|
|
|
88
88
|
const jsrepolocation = (prg.jsrepo ?? "'central'")
|
|
89
89
|
.split(',')
|
|
90
90
|
.map((x) => x === "'central'"
|
|
91
|
-
? 'https://raw.githubusercontent.com/RetireJS/retire.js/master/repository/jsrepository-
|
|
91
|
+
? 'https://raw.githubusercontent.com/RetireJS/retire.js/master/repository/jsrepository-v5.json'
|
|
92
92
|
: x);
|
|
93
93
|
const ignorefile = prg.ignorefile ?? defaultIgnoreFiles.filter((x) => fs_1.default.existsSync(x))[0];
|
|
94
94
|
const scanpath = prg.path ?? prg.jspath ?? '.';
|
package/lib/repo.js
CHANGED
|
@@ -54,6 +54,7 @@ function validateRepository(repo, replacer) {
|
|
|
54
54
|
.object({
|
|
55
55
|
below: versionValidator,
|
|
56
56
|
atOrAbove: versionValidator.optional(),
|
|
57
|
+
excludes: z.array(versionValidator).optional(),
|
|
57
58
|
severity: z.enum(keys),
|
|
58
59
|
cwe: z.array(z.string().regex(/^CWE-[0-9]+$/)).min(1),
|
|
59
60
|
identifiers: z
|
|
@@ -66,6 +66,8 @@ function configureCycloneDXJSONLogger(logger, writer, config, hash) {
|
|
|
66
66
|
logger.close = function (callback) {
|
|
67
67
|
const write = vulnsFound ? writer.err : writer.out;
|
|
68
68
|
const seen = new Map();
|
|
69
|
+
const vulnerabilitiesCyclone = new Map();
|
|
70
|
+
const includeVEX = config.outputformat === 'cyclonedxJSON1_6_VEX';
|
|
69
71
|
const components = finalResults.data
|
|
70
72
|
.filter((d) => d.results)
|
|
71
73
|
.map((r) => r.results
|
|
@@ -93,7 +95,39 @@ function configureCycloneDXJSONLogger(logger, writer, config, hash) {
|
|
|
93
95
|
return undefined;
|
|
94
96
|
}
|
|
95
97
|
const nameParts = dep.component.split('/').reverse();
|
|
98
|
+
const bomRef = purl;
|
|
99
|
+
dep.vulnerabilities?.forEach((vuln) => {
|
|
100
|
+
// Pick valid identifiers for VEX
|
|
101
|
+
const ids = vuln.identifiers?.CVE ?? (vuln.identifiers?.githubID ? [vuln.identifiers.githubID] : undefined);
|
|
102
|
+
if (!ids)
|
|
103
|
+
return;
|
|
104
|
+
ids.forEach((id) => {
|
|
105
|
+
if (!vulnerabilitiesCyclone.has(id)) {
|
|
106
|
+
const { references, advisories } = mapUrls(vuln);
|
|
107
|
+
vulnerabilitiesCyclone.set(id, {
|
|
108
|
+
id,
|
|
109
|
+
cwes: vuln.cwe.map((c) => parseInt(c.split("-")[1])),
|
|
110
|
+
description: vuln.identifiers.summary,
|
|
111
|
+
advisories: advisories,
|
|
112
|
+
references: references,
|
|
113
|
+
ratings: [
|
|
114
|
+
{
|
|
115
|
+
source: 'Retire.js',
|
|
116
|
+
severity: vuln.severity,
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
affects: [],
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
vulnerabilitiesCyclone.get(id).affects.push({
|
|
123
|
+
ref: bomRef,
|
|
124
|
+
// "vers:npm/1.2.3|>=2.0.0|<5.0.0"
|
|
125
|
+
range: "vers:npm/" + (vuln.atOrAbove ? ">=" + vuln.atOrAbove + "|" : "") + "<" + vuln.below,
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
96
129
|
const result = {
|
|
130
|
+
"bom-ref": bomRef,
|
|
97
131
|
type: 'library',
|
|
98
132
|
name: nameParts[0],
|
|
99
133
|
group: nameParts[1],
|
|
@@ -118,12 +152,13 @@ function configureCycloneDXJSONLogger(logger, writer, config, hash) {
|
|
|
118
152
|
tools: [
|
|
119
153
|
{
|
|
120
154
|
vendor: 'RetireJS',
|
|
121
|
-
name: 'retire
|
|
155
|
+
name: 'retire',
|
|
122
156
|
version: retire.version,
|
|
123
157
|
},
|
|
124
158
|
],
|
|
125
159
|
},
|
|
126
160
|
components: components,
|
|
161
|
+
vulnerabilities: includeVEX ? Array.from(vulnerabilitiesCyclone.values()) : undefined,
|
|
127
162
|
}, undefined, 2));
|
|
128
163
|
writer.close(callback);
|
|
129
164
|
};
|
|
@@ -137,6 +172,21 @@ function mapLicenses(licenses) {
|
|
|
137
172
|
return [{ license: { name: 'Commercial' } }];
|
|
138
173
|
return [{ expression: licenses[0] }];
|
|
139
174
|
}
|
|
175
|
+
function mapUrls(vulnerability) {
|
|
176
|
+
const references = [];
|
|
177
|
+
if (vulnerability.identifiers.CVE) {
|
|
178
|
+
const nvdlink = `https://nvd.nist.gov/vuln/detail/${vulnerability.identifiers.CVE[0]}`;
|
|
179
|
+
references.push({ id: vulnerability.identifiers.CVE[0], source: { name: 'NVD', url: nvdlink } });
|
|
180
|
+
}
|
|
181
|
+
if (vulnerability.identifiers.githubID) {
|
|
182
|
+
const ghsa = `https://github.com/advisories/${vulnerability.identifiers.githubID}`;
|
|
183
|
+
references.push({ id: vulnerability.identifiers.githubID, source: { name: 'GitHub Advisories', url: ghsa } });
|
|
184
|
+
}
|
|
185
|
+
const advisories = vulnerability.info
|
|
186
|
+
.filter((url) => !url.startsWith('https://nvd.nist.gov/vuln/detail/') && !url.startsWith('https://github.com/advisories/'))
|
|
187
|
+
.map((u) => ({ url: u }));
|
|
188
|
+
return { references, advisories };
|
|
189
|
+
}
|
|
140
190
|
exports.default = {
|
|
141
191
|
configure: configureCycloneDXJSONLogger,
|
|
142
192
|
};
|
package/lib/reporting.js
CHANGED
|
@@ -54,6 +54,7 @@ const loggers = {
|
|
|
54
54
|
cyclonedx: cyclonedx_1.default,
|
|
55
55
|
cyclonedxJSON: cyclonedx_json_1.default,
|
|
56
56
|
cyclonedxJSON1_6: cyclonedx_1_6_json_1.default,
|
|
57
|
+
cyclonedxJSON1_6_VEX: cyclonedx_1_6_json_1.default,
|
|
57
58
|
clean: console_1.default,
|
|
58
59
|
jsonsimple: json_1.default,
|
|
59
60
|
};
|
package/lib/retire.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
var exports = exports || {};
|
|
7
|
-
exports.version = '5.
|
|
7
|
+
exports.version = '5.4.0';
|
|
8
8
|
|
|
9
9
|
function isDefined(o) {
|
|
10
10
|
return typeof o !== 'undefined';
|
|
@@ -103,6 +103,9 @@ function check(results, repo) {
|
|
|
103
103
|
if (isDefined(vulns[i].atOrAbove) && !isAtOrAbove(result.version, vulns[i].atOrAbove)) {
|
|
104
104
|
continue;
|
|
105
105
|
}
|
|
106
|
+
if (isDefined(vulns[i].excludes) && vulns[i].excludes.includes(result.version)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
106
109
|
var vulnerability = { info: vulns[i].info, below: vulns[i].below, atOrAbove: vulns[i].atOrAbove };
|
|
107
110
|
if (vulns[i].severity) {
|
|
108
111
|
vulnerability.severity = vulns[i].severity;
|
package/lib/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "Erlend Oftedal <erlend@oftedal.no>",
|
|
3
3
|
"name": "retire",
|
|
4
4
|
"description": "Retire is a tool for detecting use of vulnerable libraries",
|
|
5
|
-
"version": "5.
|
|
5
|
+
"version": "5.4.0",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"main": "./lib/retire.js",
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"ansi-colors": "^4.1.1",
|
|
17
|
-
"astronomical": "^2.
|
|
17
|
+
"astronomical": "^2.1.1-rc.1",
|
|
18
18
|
"commander": "^10.0.1",
|
|
19
19
|
"proxy-agent": "^6.4.0",
|
|
20
20
|
"uuid": "^9.0.1",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"zod": "^3.22.4"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@types/jest": "^29.5.14",
|
|
26
25
|
"@types/chai": "^4.3.17",
|
|
26
|
+
"@types/jest": "^29.5.14",
|
|
27
27
|
"@types/node": "^18.13.0",
|
|
28
28
|
"@types/uuid": "^9.0.0",
|
|
29
29
|
"@typescript-eslint/eslint-plugin": "^7.1.1",
|