retire 3.2.3 → 4.0.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 +9 -0
- package/README.md +1 -9
- package/lib/cli.d.ts +2 -0
- package/lib/cli.js +195 -0
- package/lib/repo.d.ts +4 -0
- package/lib/repo.js +148 -103
- package/lib/reporters/console.d.ts +3 -0
- package/lib/reporters/console.js +66 -39
- package/lib/reporters/cyclonedx-json.d.ts +3 -0
- package/lib/reporters/cyclonedx-json.js +71 -42
- package/lib/reporters/cyclonedx.d.ts +3 -0
- package/lib/reporters/cyclonedx.js +62 -34
- package/lib/reporters/depcheck.d.ts +3 -0
- package/lib/reporters/depcheck.js +79 -51
- package/lib/reporters/json.d.ts +3 -0
- package/lib/reporters/json.js +56 -28
- package/lib/reporting.d.ts +36 -0
- package/lib/reporting.js +107 -88
- package/lib/resolve.d.ts +4 -0
- package/lib/resolve.js +52 -100
- package/lib/retire.js +1 -10
- package/lib/scanner.d.ts +4 -0
- package/lib/scanner.js +113 -119
- package/lib/types.d.ts +83 -0
- package/lib/types.js +10 -0
- package/lib/utils.d.ts +11 -0
- package/lib/utils.js +27 -53
- package/package.json +31 -10
- package/bin/retire +0 -236
package/lib/reporting.js
CHANGED
|
@@ -1,96 +1,115 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
15
24
|
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.open = exports.hash = void 0;
|
|
30
|
+
const fs = __importStar(require("fs"));
|
|
31
|
+
const crypto = __importStar(require("crypto"));
|
|
32
|
+
const console_1 = __importDefault(require("./reporters/console"));
|
|
33
|
+
const json_1 = __importDefault(require("./reporters/json"));
|
|
34
|
+
const depcheck_1 = __importDefault(require("./reporters/depcheck"));
|
|
35
|
+
const cyclonedx_1 = __importDefault(require("./reporters/cyclonedx"));
|
|
36
|
+
const cyclonedx_json_1 = __importDefault(require("./reporters/cyclonedx-json"));
|
|
37
|
+
const loggers = {
|
|
38
|
+
console: console_1.default,
|
|
39
|
+
text: console_1.default,
|
|
40
|
+
json: json_1.default,
|
|
41
|
+
depcheck: depcheck_1.default,
|
|
42
|
+
cyclonedx: cyclonedx_1.default,
|
|
43
|
+
cyclonedxJSON: cyclonedx_json_1.default,
|
|
44
|
+
clean: console_1.default,
|
|
45
|
+
jsonsimple: json_1.default
|
|
46
|
+
};
|
|
47
|
+
let colorwarn = (x) => { return x; };
|
|
48
|
+
let verbose = false;
|
|
24
49
|
function hashContent(hash, content) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
50
|
+
const h = crypto.createHash(hash);
|
|
51
|
+
h.update(content);
|
|
52
|
+
return h.digest('hex');
|
|
28
53
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
sha512: (file) => hashContent('sha512', file),
|
|
54
|
+
exports.hash = {
|
|
55
|
+
md5: (file) => hashContent('md5', file),
|
|
56
|
+
sha1: (file) => hashContent('sha1', file),
|
|
57
|
+
sha256: (file) => hashContent('sha256', file),
|
|
58
|
+
sha512: (file) => hashContent('sha512', file),
|
|
35
59
|
};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
out: console.log,
|
|
41
|
-
err: function(x) { console.warn(colorwarn(x)); },
|
|
42
|
-
close : function() { }
|
|
60
|
+
const writer = {
|
|
61
|
+
out: console.log,
|
|
62
|
+
err: (x) => { console.warn(colorwarn(x)); },
|
|
63
|
+
close: () => { return; }
|
|
43
64
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
close: function() { writer.close(); }
|
|
65
|
+
const logger = {
|
|
66
|
+
info: (x) => { writer.out(x); },
|
|
67
|
+
debug: (x) => { if (verbose)
|
|
68
|
+
writer.out(x); },
|
|
69
|
+
warn: (x) => { writer.err(x); },
|
|
70
|
+
error: (x) => { writer.err(x); },
|
|
71
|
+
logDependency: () => { return; },
|
|
72
|
+
logVulnerableDependency: () => { return; },
|
|
73
|
+
close: () => writer.close()
|
|
54
74
|
};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
75
|
+
;
|
|
58
76
|
function configureFileWriter(config) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
if (!config.outputpath)
|
|
78
|
+
return;
|
|
79
|
+
const fileDescriptor = fs.openSync(config.outputpath, "w");
|
|
80
|
+
if (fileDescriptor < 0) {
|
|
81
|
+
console.error(`Could not open ${config.outputpath} for writing`);
|
|
82
|
+
process.exit(9);
|
|
83
|
+
}
|
|
84
|
+
const fileOutput = {
|
|
85
|
+
fileDescriptor,
|
|
86
|
+
stream: fs.createWriteStream('', { fd: fileDescriptor, autoClose: false })
|
|
87
|
+
};
|
|
88
|
+
const writeToFile = (message) => {
|
|
89
|
+
fileOutput.stream.write(message);
|
|
90
|
+
fileOutput.stream.write('\n');
|
|
91
|
+
};
|
|
92
|
+
writer.out = writer.err = writeToFile;
|
|
93
|
+
writer.close = () => {
|
|
94
|
+
fileOutput.stream.on('finish', () => {
|
|
95
|
+
fs.closeSync(fileOutput.fileDescriptor);
|
|
96
|
+
});
|
|
97
|
+
fileOutput.stream.end();
|
|
98
|
+
};
|
|
78
99
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
exports.hash = hash;
|
|
100
|
+
function open(config) {
|
|
101
|
+
var _a;
|
|
102
|
+
verbose = (_a = config.verbose) !== null && _a !== void 0 ? _a : false;
|
|
103
|
+
if (config.colors)
|
|
104
|
+
colorwarn = config.colorwarn;
|
|
105
|
+
const format = config.outputformat || "console";
|
|
106
|
+
if (!(format in loggers)) {
|
|
107
|
+
console.warn(`Invalid outputformat: ${format}`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
loggers[format].configure(logger, writer, config, exports.hash);
|
|
111
|
+
configureFileWriter(config);
|
|
112
|
+
return logger;
|
|
113
|
+
}
|
|
114
|
+
exports.open = open;
|
|
115
|
+
;
|
package/lib/resolve.d.ts
ADDED
package/lib/resolve.js
CHANGED
|
@@ -1,102 +1,54 @@
|
|
|
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
|
-
if (dedup[id]) continue;
|
|
30
|
-
dedup[id] = true;
|
|
31
|
-
var d = {
|
|
32
|
-
module: { component: i, version: o.dep.dependencies[i].version }
|
|
33
|
-
};
|
|
34
|
-
if (o.dep.dependencies[i].path) {
|
|
35
|
-
d.file = "node_modules" + o.dep.dependencies[i].path.split("node_modules").slice(1).join("node_modules") + '/package.json';
|
|
36
|
-
}
|
|
37
|
-
deps.push(d);
|
|
38
|
-
stack.push({parent: d, dep: o.dep.dependencies[i], level: o.level + 1});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function getNodeDependencies(path, limit) {
|
|
44
|
-
var events = new emitter();
|
|
45
|
-
readInstalled(path, {}, function (er, pkginfo) {
|
|
46
|
-
var deps = [];
|
|
47
|
-
if (limit) {
|
|
48
|
-
var packages = JSON.parse(fs.readFileSync(path +'/package.json'));
|
|
49
|
-
filter = [];
|
|
50
|
-
|
|
51
|
-
var filter = packages.dependencies ? Object.keys(packages.dependencies) : [];
|
|
52
|
-
|
|
53
|
-
Object.keys(pkginfo.dependencies)
|
|
54
|
-
.filter(function(d) { return !pkginfo.dependencies[d]._requiredBy || pkginfo.dependencies[d]._requiredBy.indexOf("/") > -1 || pkginfo.dependencies[d]._requiredBy.indexOf("#DEV:/") > -1; })
|
|
55
|
-
.filter(function(d) { return filter.indexOf(d) == -1; })
|
|
56
|
-
.forEach(function(d) { delete pkginfo.dependencies[d]; });
|
|
57
|
-
}
|
|
58
|
-
var notInstalled = Object.keys(pkginfo.dependencies).filter(function (d) {
|
|
59
|
-
return !pkginfo.dependencies[d].path;
|
|
60
|
-
});
|
|
61
|
-
if (notInstalled.length > 0) {
|
|
62
|
-
return events.emit('error', 'Could not find dependencies: ' + notInstalled.join(', ') + '. You may need to run npm install');
|
|
63
|
-
}
|
|
64
|
-
listdep({file: 'package.json',component: pkginfo.name, version: pkginfo.version}, pkginfo, 1, deps);
|
|
65
|
-
events.emit('done', deps);
|
|
66
|
-
});
|
|
67
|
-
return events;
|
|
68
|
-
}
|
|
69
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.scanJsFiles = void 0;
|
|
27
|
+
const fs = __importStar(require("fs"));
|
|
28
|
+
const walkdir = __importStar(require("walkdir"));
|
|
70
29
|
function scanJsFiles(path, options) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
30
|
+
const finder = walkdir.find(path, { "follow_symlinks": false, "no_return": true });
|
|
31
|
+
const ext = (options.ext || "js").split(",").map((e) => `.${e}`);
|
|
32
|
+
function onFile(file) {
|
|
33
|
+
if (ext.some((e) => file.endsWith(e))) {
|
|
34
|
+
finder.emit('jsfile', file);
|
|
35
|
+
}
|
|
36
|
+
if (file.match(/\/bower.json$/)) {
|
|
37
|
+
finder.emit('bowerfile', file);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
finder.on('file', onFile);
|
|
41
|
+
finder.on('link', (link) => {
|
|
42
|
+
if (fs.existsSync(link)) {
|
|
43
|
+
const file = fs.realpathSync(link);
|
|
44
|
+
if (fs.lstatSync(file).isFile()) {
|
|
45
|
+
onFile(link);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
options.log.warn(`Could not follow symlink: ${link}`);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return finder;
|
|
93
53
|
}
|
|
94
|
-
|
|
95
|
-
exports.scanJsFiles = function(path, options) {
|
|
96
|
-
return scanJsFiles(path, options);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
exports.getNodeDependencies = function(path, limit) {
|
|
100
|
-
return getNodeDependencies(path, limit);
|
|
101
|
-
};
|
|
102
|
-
|
|
54
|
+
exports.scanJsFiles = scanJsFiles;
|
package/lib/retire.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
var exports = exports || {};
|
|
7
|
-
exports.version = '
|
|
7
|
+
exports.version = '4.0.0';
|
|
8
8
|
|
|
9
9
|
function isDefined(o) {
|
|
10
10
|
return typeof o !== 'undefined';
|
|
@@ -171,14 +171,5 @@ exports.scanFileContent = function(content, repo, hasher) {
|
|
|
171
171
|
return check(result, repo);
|
|
172
172
|
};
|
|
173
173
|
|
|
174
|
-
exports.scanNodeDependency = function(dependency, npmrepo, options) {
|
|
175
|
-
if (!isDefined(dependency.version)) {
|
|
176
|
-
if (options.log) options.log.warn('Missing version for ' + dependency.component + '. Need to run npm install ?');
|
|
177
|
-
return [];
|
|
178
|
-
}
|
|
179
|
-
if (!isDefined(npmrepo[dependency.component])) return [{component: dependency.component, version: dependency.version, file: dependency.file}];
|
|
180
|
-
return check([dependency], npmrepo);
|
|
181
|
-
};
|
|
182
|
-
|
|
183
174
|
|
|
184
175
|
|
package/lib/scanner.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Finding, Options, Repository } from "./types";
|
|
2
|
+
export declare function scanJsFile(file: string, repo: Repository, options: Options): void;
|
|
3
|
+
export declare function scanBowerFile(file: string, repo: Repository, options: Options): void;
|
|
4
|
+
export declare function on(event: 'vulnerable-dependency-found' | 'dependency-found', handler: (finding: Finding) => void): void;
|
package/lib/scanner.js
CHANGED
|
@@ -1,138 +1,132 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.on = exports.scanBowerFile = exports.scanJsFile = void 0;
|
|
27
|
+
const events_1 = require("events");
|
|
28
|
+
const retire = __importStar(require("./retire"));
|
|
29
|
+
const fs = __importStar(require("fs"));
|
|
30
|
+
const crypto = __importStar(require("crypto"));
|
|
31
|
+
const path = __importStar(require("path"));
|
|
32
|
+
const events = new events_1.EventEmitter();
|
|
33
|
+
const hash = {
|
|
34
|
+
'sha1': (data) => {
|
|
35
|
+
const shasum = crypto.createHash('sha1');
|
|
36
|
+
shasum.update(data);
|
|
37
|
+
return shasum.digest('hex');
|
|
38
|
+
}
|
|
17
39
|
};
|
|
18
|
-
|
|
19
40
|
function emitResults(finding, options) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
41
|
+
if (options.ignore)
|
|
42
|
+
removeIgnored(finding.results, options.ignore);
|
|
43
|
+
if (!options.verbose)
|
|
44
|
+
finding.results = finding.results.filter(f => retire.isVulnerable([f]));
|
|
45
|
+
if (finding.results.length == 0)
|
|
46
|
+
return;
|
|
47
|
+
if (retire.isVulnerable(finding.results)) {
|
|
48
|
+
events.emit('vulnerable-dependency-found', finding);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
events.emit('dependency-found', finding);
|
|
52
|
+
}
|
|
29
53
|
}
|
|
30
|
-
|
|
31
54
|
function shouldIgnorePath(fileSpecs, ignores) {
|
|
32
|
-
|
|
33
|
-
return
|
|
34
|
-
|
|
35
|
-
});
|
|
36
|
-
});
|
|
55
|
+
var _a, _b;
|
|
56
|
+
return (_b = (_a = ignores.paths) === null || _a === void 0 ? void 0 : _a.some((i) => {
|
|
57
|
+
return fileSpecs.some((j) => i.test(j) || i.test(path.resolve(j)));
|
|
58
|
+
})) !== null && _b !== void 0 ? _b : false;
|
|
37
59
|
}
|
|
38
|
-
|
|
39
60
|
function removeIgnored(results, ignores) {
|
|
40
|
-
|
|
41
|
-
results.forEach(function(r) {
|
|
42
|
-
if (!r.hasOwnProperty('vulnerabilities')) return;
|
|
43
|
-
ignores.descriptors.forEach(function(i) {
|
|
44
|
-
if (r.component !== i.component) return;
|
|
45
|
-
if (i.version && r.version !== i.version) return;
|
|
46
|
-
if (i.severity && r.severity !== i.severity) return;
|
|
47
|
-
if (i.identifiers) {
|
|
48
|
-
removeIgnoredVulnerabilitiesByIdentifier(i.identifiers, r);
|
|
61
|
+
if (!("descriptors" in ignores))
|
|
49
62
|
return;
|
|
50
|
-
|
|
51
|
-
|
|
63
|
+
results.forEach((r) => {
|
|
64
|
+
var _a, _b;
|
|
65
|
+
if (!("vulnerabilities" in r))
|
|
66
|
+
return;
|
|
67
|
+
(_a = ignores.descriptors) === null || _a === void 0 ? void 0 : _a.filter((d) => "component" in d).forEach((i) => {
|
|
68
|
+
var _a;
|
|
69
|
+
if (r.component !== i.component)
|
|
70
|
+
return;
|
|
71
|
+
if (i.version && r.version !== i.version)
|
|
72
|
+
return;
|
|
73
|
+
if (i.severity) { //Remove vulnerabilities with the severity we want to drop
|
|
74
|
+
r.vulnerabilities = (_a = r.vulnerabilities) === null || _a === void 0 ? void 0 : _a.filter(v => v.severity != i.severity);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (i.identifiers) {
|
|
78
|
+
removeIgnoredVulnerabilitiesByIdentifier(Object.assign({}, i.identifiers), r);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
r.vulnerabilities = [];
|
|
82
|
+
});
|
|
83
|
+
if (((_b = r.vulnerabilities) === null || _b === void 0 ? void 0 : _b.length) === 0)
|
|
84
|
+
delete r.vulnerabilities;
|
|
52
85
|
});
|
|
53
|
-
if (r.vulnerabilities.length === 0) delete r.vulnerabilities;
|
|
54
|
-
});
|
|
55
86
|
}
|
|
56
|
-
|
|
57
87
|
function removeIgnoredVulnerabilitiesByIdentifier(identifiers, result) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
88
|
+
var _a;
|
|
89
|
+
result.vulnerabilities = (_a = result.vulnerabilities) === null || _a === void 0 ? void 0 : _a.filter((v) => {
|
|
90
|
+
if (!("identifiers" in v))
|
|
91
|
+
return true;
|
|
92
|
+
return !Object.entries(identifiers || {}).every(([key, value]) => hasIdentifier(Object.assign({}, v.identifiers), key, value));
|
|
93
|
+
});
|
|
62
94
|
}
|
|
63
|
-
function hasIdentifier(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
95
|
+
function hasIdentifier(identifiers, key, value) {
|
|
96
|
+
if (!(key in identifiers))
|
|
97
|
+
return false;
|
|
98
|
+
const identifier = identifiers[key];
|
|
99
|
+
return Array.isArray(identifier) ? identifier.some((x) => x === value) : identifier === value;
|
|
67
100
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
101
|
function scanJsFile(file, repo, options) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
var results = retire.scanFileName(file, repo);
|
|
75
|
-
if (!results || results.length === 0) {
|
|
76
|
-
results = retire.scanFileContent(fs.readFileSync(file), repo, hash);
|
|
77
|
-
}
|
|
78
|
-
emitResults({file: file, results: results}, options);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
function scanDependencies(dependencies, nodeRepo, options) {
|
|
83
|
-
for (var i in dependencies) {
|
|
84
|
-
var dependency = dependencies[i];
|
|
85
|
-
var fileSpecs = [toModulePath(dependency)];
|
|
86
|
-
if (dependency.component) {
|
|
87
|
-
fileSpecs.push(dependency.component);
|
|
102
|
+
if (options.ignore && shouldIgnorePath([file], options.ignore)) {
|
|
103
|
+
return;
|
|
88
104
|
}
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
|
|
105
|
+
let results = retire.scanFileName(file, repo);
|
|
106
|
+
if (!results || results.length === 0) {
|
|
107
|
+
results = retire.scanFileContent(fs.readFileSync(file, "utf-8"), repo, hash);
|
|
92
108
|
}
|
|
93
|
-
|
|
94
|
-
emitResults({file: dependencies[i].file, results: results}, options);
|
|
95
|
-
}
|
|
109
|
+
emitResults({ file: file, results: results }, options);
|
|
96
110
|
}
|
|
97
|
-
|
|
98
|
-
function toModulePath(dep) {
|
|
99
|
-
function f(d) {
|
|
100
|
-
if (d.parent) return f(d.parent) + '/node_modules/' + d.component;
|
|
101
|
-
return '';
|
|
102
|
-
}
|
|
103
|
-
return path.resolve(f(dep).substring(1));
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
exports.scanJsFile = scanJsFile;
|
|
108
112
|
function scanBowerFile(file, repo, options) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
if (options.ignore && shouldIgnorePath([file], options.ignore)) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
const bower = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
118
|
+
if (bower.version) {
|
|
119
|
+
const results = retire.check(bower.name, bower.version, repo);
|
|
120
|
+
emitResults({ file: file, results: results }, options);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
options.log.warn(`Could not parse file: ${file}`);
|
|
117
125
|
}
|
|
118
|
-
} catch (e) {
|
|
119
|
-
options.log.warn('Could not parse file: ' + file);
|
|
120
|
-
}
|
|
121
126
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
exports.scanJsFile = function(file, repo, options) {
|
|
129
|
-
return scanJsFile(file, repo, options);
|
|
130
|
-
};
|
|
131
|
-
exports.scanBowerFile = function(file, repo, options) {
|
|
132
|
-
return scanBowerFile(file, repo, options);
|
|
133
|
-
};
|
|
134
|
-
exports.on = function(name, listener) {
|
|
135
|
-
events.on(name, listener);
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
|
|
127
|
+
exports.scanBowerFile = scanBowerFile;
|
|
128
|
+
function on(event, handler) {
|
|
129
|
+
events.on(event, handler);
|
|
130
|
+
}
|
|
131
|
+
exports.on = on;
|
|
132
|
+
;
|