check = function (component, version, repo) { return check([{component: component, version: version}], repo); }
...
function scanBowerFile(file, repo, options) {
if (options.ignore && shouldIgnorePath([file], options.ignore)) {
return;
}
try {
var bower = JSON.parse(fs.readFileSync(file));
if (bower.version) {
var results = retire.check(bower.name, bower.version, repo);
printResults(file, results, options);
}
} catch (e) {
log(options).warn('Could not parse file: ' + file);
}
}
...
isVulnerable = function (results) { for (var r in results) { if (results[r].hasOwnProperty('vulnerabilities')) return true; } return false; }
...
shasum.update(data);
return shasum.digest('hex');
}
};
function printResults(file, results, options) {
removeIgnored(results, options.ignore);
if (!retire.isVulnerable(results) && !options.verbose) return;
var logger = log(options).info;
if (retire.isVulnerable(results)) {
logger = log(options).warn;
events.emit('vulnerable-dependency-found', {file: file, results: results});
} else {
events.emit('dependency-found', {file: file, results: results});
}
...
replaceVersion = function (jsRepoJsonAsText) { return jsRepoJsonAsText.replace(/§§version§§/g, '[0-9][0-9.a-z_\\\\-]+'); }
n/a
scanFileContent = function (content, repo, hasher) { var result = scan(content, 'filecontent', repo); if (result.length === 0) { result = scan(content, 'filecontentreplace', repo, replacementMatch); } if (result.length === 0) { result = scanhash(hasher.sha1(content), repo); } return check(result, repo); }
...
function scanJsFile(file, repo, options) {
if (options.ignore && shouldIgnorePath([file], options.ignore)) {
return;
}
var results = retire.scanFileName(file, repo);
if (!results || results.length === 0) {
results = retire.scanFileContent(fs.readFileSync(file), repo, hash);
}
printResults(file, results, options);
}
function printParent(comp, options) {
if ('parent' in comp) printParent(comp.parent, options);
log(options).info(new Array(comp.level).join(' ') + (comp.parent ? String.fromCharCode(8627) + ' ' : '
x27;) + comp.component + ' ' + comp.version);
...
scanFileName = function (fileName, repo) { var result = scan(fileName, 'filename', repo); return check(result, repo); }
...
}
function scanJsFile(file, repo, options) {
if (options.ignore && shouldIgnorePath([file], options.ignore)) {
return;
}
var results = retire.scanFileName(file, repo);
if (!results || results.length === 0) {
results = retire.scanFileContent(fs.readFileSync(file), repo, hash);
}
printResults(file, results, options);
}
function printParent(comp, options) {
...
scanNodeDependency = function (dependency, npmrepo) { if (!isDefined(dependency.version)) { console.warn('Missing version for ' + dependency.component + '. Need to run npm install ?'); return []; } if (!isDefined(npmrepo[dependency.component])) return []; return check([dependency], npmrepo); }
...
}
function scanDependencies(dependencies, nodeRepo, options) {
for (var i in dependencies) {
if (options.ignore && shouldIgnorePath([dependencies[i].component, toModulePath(dependencies[i])], options.ignore)) {
continue;
}
results = retire.scanNodeDependency(dependencies[i], nodeRepo);
if (retire.isVulnerable(results)) {
events.emit('vulnerable-dependency-found', {results: results});
var result = results[0]; //Only single scan here
log(options).warn(result.component + ' ' + result.version + ' has known vulnerabilities: ' + printVulnerability
(result, options));
if (result.parent) {
printParent(result, options);
}
...
scanUri = function (uri, repo) { var result = scan(uri, 'uri', repo); return check(result, repo); }
n/a
loadrepository = function (repoUrl, options) { options = utils.extend(options, { process : retire.replaceVersion }); if (options.nocache) { return loadJson(repoUrl, options); } return loadFromCache(repoUrl, options.cachedir, options); }
n/a
loadrepositoryFromFile = function (filepath, options) { options = utils.extend(options, { process : retire.replaceVersion }); return loadJsonFromFile(filepath, options); }
n/a
getNodeDependencies = function (path, limit) { return getNodeDependencies(path, limit); }
n/a
scanJsFiles = function (path) { return scanJsFiles(path); }
n/a
check = function (component, version, repo) { return check([{component: component, version: version}], repo); }
...
function scanBowerFile(file, repo, options) {
if (options.ignore && shouldIgnorePath([file], options.ignore)) {
return;
}
try {
var bower = JSON.parse(fs.readFileSync(file));
if (bower.version) {
var results = retire.check(bower.name, bower.version, repo);
printResults(file, results, options);
}
} catch (e) {
log(options).warn('Could not parse file: ' + file);
}
}
...
isVulnerable = function (results) { for (var r in results) { if (results[r].hasOwnProperty('vulnerabilities')) return true; } return false; }
...
shasum.update(data);
return shasum.digest('hex');
}
};
function printResults(file, results, options) {
removeIgnored(results, options.ignore);
if (!retire.isVulnerable(results) && !options.verbose) return;
var logger = log(options).info;
if (retire.isVulnerable(results)) {
logger = log(options).warn;
events.emit('vulnerable-dependency-found', {file: file, results: results});
} else {
events.emit('dependency-found', {file: file, results: results});
}
...
replaceVersion = function (jsRepoJsonAsText) { return jsRepoJsonAsText.replace(/§§version§§/g, '[0-9][0-9.a-z_\\\\-]+'); }
n/a
scanFileContent = function (content, repo, hasher) { var result = scan(content, 'filecontent', repo); if (result.length === 0) { result = scan(content, 'filecontentreplace', repo, replacementMatch); } if (result.length === 0) { result = scanhash(hasher.sha1(content), repo); } return check(result, repo); }
...
function scanJsFile(file, repo, options) {
if (options.ignore && shouldIgnorePath([file], options.ignore)) {
return;
}
var results = retire.scanFileName(file, repo);
if (!results || results.length === 0) {
results = retire.scanFileContent(fs.readFileSync(file), repo, hash);
}
printResults(file, results, options);
}
function printParent(comp, options) {
if ('parent' in comp) printParent(comp.parent, options);
log(options).info(new Array(comp.level).join(' ') + (comp.parent ? String.fromCharCode(8627) + ' ' : '
x27;) + comp.component + ' ' + comp.version);
...
scanFileName = function (fileName, repo) { var result = scan(fileName, 'filename', repo); return check(result, repo); }
...
}
function scanJsFile(file, repo, options) {
if (options.ignore && shouldIgnorePath([file], options.ignore)) {
return;
}
var results = retire.scanFileName(file, repo);
if (!results || results.length === 0) {
results = retire.scanFileContent(fs.readFileSync(file), repo, hash);
}
printResults(file, results, options);
}
function printParent(comp, options) {
...
scanNodeDependency = function (dependency, npmrepo) { if (!isDefined(dependency.version)) { console.warn('Missing version for ' + dependency.component + '. Need to run npm install ?'); return []; } if (!isDefined(npmrepo[dependency.component])) return []; return check([dependency], npmrepo); }
...
}
function scanDependencies(dependencies, nodeRepo, options) {
for (var i in dependencies) {
if (options.ignore && shouldIgnorePath([dependencies[i].component, toModulePath(dependencies[i])], options.ignore)) {
continue;
}
results = retire.scanNodeDependency(dependencies[i], nodeRepo);
if (retire.isVulnerable(results)) {
events.emit('vulnerable-dependency-found', {results: results});
var result = results[0]; //Only single scan here
log(options).warn(result.component + ' ' + result.version + ' has known vulnerabilities: ' + printVulnerability
(result, options));
if (result.parent) {
printParent(result, options);
}
...
scanUri = function (uri, repo) { var result = scan(uri, 'uri', repo); return check(result, repo); }
n/a
on = function (name, listener) { events.on(name, listener); }
...
} else {
if (fs.existsSync(path.resolve(cachedir, cache[url].date + '.json'))) {
fs.unlink(path.resolve(cachedir, cache[url].date + '.json'));
}
}
}
var events = new emitter();
loadJson(url, options).on('done', function(data) {
cache[url] = { date : now, file : now + '.json' };
fs.writeFileSync(path.resolve(cachedir, cache[url].file), JSON.stringify(data), { encoding : 'utf8' });
fs.writeFileSync(cacheIndex, JSON.stringify(cache), { encoding : 'utf8' });
events.emit('done', data);
}).on('stop', forward(events, 'stop'));
return events;
}
...
scanBowerFile = function (file, repo, options) { return scanBowerFile(file, repo, options); }
n/a
scanDependencies = function (dependencies, nodeRepo, options) { return scanDependencies(dependencies, nodeRepo, options); }
n/a
scanJsFile = function (file, repo, options) { return scanJsFile(file, repo, options); }
n/a
detect = function (ar, fn) { for(var i in ar) { if (fn(ar[i])) return ar[i]; } return undefined; }
...
}
string += vulnerability.info.join(options.outputformat === 'clean' ? '\n' : ' ');
});
return string;
}
function shouldIgnorePath(fileSpecs, ignores) {
return utils.detect(ignores.paths, function(i) {
return utils.detect(fileSpecs, function(j) {
return j.indexOf(i) === 0 || j.indexOf(path.resolve(i)) === 0 ;
});
});
}
function removeIgnored(results, ignores) {
...
every = function (things, predicate){ return Object.keys(things) .map(function(k) { return predicate(k, things[k]) }) .reduce(function(x,y) { return x && y }, true); }
...
if (r.vulnerabilities.length === 0) delete r.vulnerabilities;
});
}
function removeIgnoredVulnerabilitiesByIdentifier(identifiers, result) {
result.vulnerabilities = result.vulnerabilities.filter(function(v) {
if (!v.hasOwnProperty("identifiers")) return true;
return !utils.every(identifiers, function(key, value) { return hasIdentifier(v, key
, value); });
});
}
function hasIdentifier(vulnerability, key, value) {
if (!vulnerability.identifiers.hasOwnProperty(key)) return false;
var identifier = vulnerability.identifiers[key];
return Array.isArray(identifier) ? identifier.some(function(x) { return x === value; }) : identifier === value;
}
...
extend = function (o, a) { var result = exports.pick(o, Object.keys(o)); exports.map(a, function(v,k){ result[k] = v; }); return result; }
...
fs.writeFileSync(cacheIndex, JSON.stringify(cache), { encoding : 'utf8' });
events.emit('done', data);
}).on('stop', forward(events, 'stop'));
return events;
}
exports.loadrepository = function(repoUrl, options) {
options = utils.extend(options, { process : retire.replaceVersion });
if (options.nocache) {
return loadJson(repoUrl, options);
}
return loadFromCache(repoUrl, options.cachedir, options);
};
exports.loadrepositoryFromFile = function(filepath, options) {
...
find = function (ar, fn) { for(var i in ar) { if (fn(ar[i])) return ar[i]; } return undefined; }
...
listdep({component: pkginfo.name, version: pkginfo.version}, pkginfo, 1, deps);
events.emit('done', deps);
});
return events;
}
function scanJsFiles(path) {
var finder = walkdir.find(path);
finder.on('file', function (file) {
if (file.match(/\.js$/)) {
finder.emit('jsfile', file);
}
if (file.match(/\/bower.json$/)) {
finder.emit('bowerfile', file);
}
...
flatten = function (e) { return e.reduce(function(x,y) { return x.concat(y); }, []); }
...
component.vulnerabilities.forEach(function(vulnerability){
string += options.outputformat === 'clean' ? '\n ' : ' ';
if (vulnerability.severity) {
string += 'severity: ' + vulnerability.severity + '; ';
}
if (vulnerability.identifiers) {
string += utils.map(vulnerability.identifiers, function(id, name) {
return name + ': ' + utils.flatten([id]).join(' ');
}).join(', ') + '; ';
}
string += vulnerability.info.join(options.outputformat === 'clean' ? '\n' : ' ');
});
return string;
}
...
forwardEvent = function (emitter, event) { return function() { emitter.emit([event].concat(arguments)); }; }
n/a
log = function (options) { return { info : info(options), warn : warn(options), verbose : options.verbose ? info(options) : function() {} }; }
n/a
map = function (o, fn) { return Object.keys(o).map(function(k) { return fn(o[k], k); }); }
...
var string = '';
component.vulnerabilities.forEach(function(vulnerability){
string += options.outputformat === 'clean' ? '\n ' : ' ';
if (vulnerability.severity) {
string += 'severity: ' + vulnerability.severity + '; ';
}
if (vulnerability.identifiers) {
string += utils.map(vulnerability.identifiers, function(id, name) {
return name + ': ' + utils.flatten([id]).join(' ');
}).join(', ') + '; ';
}
string += vulnerability.info.join(options.outputformat === 'clean' ? '\n' : ' ');
});
return string;
}
...
pick = function (p, keys) { var result = {}; keys.forEach(function(k) { if (p.hasOwnProperty(k)) { result[k] = p[k]; } }); return result; }
...
result[k] = p[k];
}
});
return result;
};
exports.extend = function(o, a) {
var result = exports.pick(o, Object.keys(o));
exports.map(a, function(v,k){ result[k] = v; });
return result;
};
exports.map = function(o, fn) {
return Object.keys(o).map(function(k) { return fn(o[k], k); });
};
...