@contrast/contrast 1.0.5 → 1.0.8
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/.prettierignore +0 -5
- package/dist/audit/autodetection/autoDetectLanguage.js +3 -3
- package/dist/audit/catalogueApplication/catalogueApplication.js +23 -5
- package/dist/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +4 -2
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/dist/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/dist/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +5 -5
- package/dist/audit/languageAnalysisEngine/getProjectRootFilenames.js +9 -9
- package/dist/audit/languageAnalysisEngine/index.js +2 -2
- package/dist/audit/languageAnalysisEngine/languageAnalysisFactory.js +6 -27
- package/dist/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +25 -5
- package/dist/audit/languageAnalysisEngine/report/commonReportingFunctions.js +99 -20
- package/dist/audit/languageAnalysisEngine/report/models/reportListModel.js +2 -1
- package/dist/audit/languageAnalysisEngine/report/models/reportOutputModel.js +24 -0
- package/dist/audit/languageAnalysisEngine/report/models/reportSeverityModel.js +3 -1
- package/dist/audit/languageAnalysisEngine/report/models/severityCountModel.js +16 -0
- package/dist/audit/languageAnalysisEngine/report/reportingFeature.js +35 -14
- package/dist/audit/languageAnalysisEngine/report/utils/reportUtils.js +58 -47
- package/dist/audit/languageAnalysisEngine/sendSnapshot.js +65 -3
- package/dist/audit/save.js +29 -0
- package/dist/commands/audit/auditController.js +22 -6
- package/dist/commands/audit/help.js +24 -1
- package/dist/commands/audit/processAudit.js +8 -2
- package/dist/commands/audit/saveFile.js +7 -3
- package/dist/commands/scan/processScan.js +1 -1
- package/dist/commands/scan/sca/scaAnalysis.js +48 -11
- package/dist/common/HTTPClient.js +56 -15
- package/dist/common/errorHandling.js +6 -1
- package/dist/common/versionChecker.js +20 -5
- package/dist/constants/constants.js +13 -3
- package/dist/constants/locales.js +15 -12
- package/dist/constants.js +9 -4
- package/dist/index.js +4 -3
- package/dist/lambda/analytics.js +11 -0
- package/dist/lambda/lambda.js +35 -4
- package/dist/lambda/types.js +13 -0
- package/dist/sbom/generateSbom.js +4 -3
- package/dist/scaAnalysis/common/formatMessage.js +46 -1
- package/dist/scaAnalysis/common/treeUpload.js +1 -3
- package/dist/scaAnalysis/go/goAnalysis.js +17 -0
- package/dist/scaAnalysis/go/goParseDeps.js +158 -0
- package/dist/scaAnalysis/go/goReadDepFile.js +21 -0
- package/dist/scaAnalysis/java/analysis.js +11 -22
- package/dist/scaAnalysis/java/index.js +6 -6
- package/dist/scaAnalysis/java/javaBuildDepsParser.js +14 -1
- package/dist/scaAnalysis/javascript/analysis.js +110 -0
- package/dist/scaAnalysis/javascript/index.js +41 -0
- package/dist/scaAnalysis/php/analysis.js +89 -0
- package/dist/scaAnalysis/php/index.js +10 -0
- package/dist/scaAnalysis/python/analysis.js +42 -0
- package/dist/scaAnalysis/python/index.js +10 -0
- package/dist/scaAnalysis/ruby/analysis.js +226 -0
- package/dist/scaAnalysis/ruby/index.js +10 -0
- package/dist/scan/autoDetection.js +8 -4
- package/dist/scan/fileUtils.js +26 -8
- package/dist/scan/formatScanOutput.js +18 -17
- package/dist/scan/models/groupedResultsModel.js +1 -1
- package/dist/scan/models/scanResultsModel.js +3 -1
- package/dist/scan/populateProjectIdAndProjectName.js +2 -1
- package/dist/scan/scan.js +5 -3
- package/dist/scan/scanConfig.js +6 -1
- package/dist/scan/scanController.js +26 -6
- package/dist/scan/scanResults.js +20 -6
- package/dist/utils/commonApi.js +4 -1
- package/dist/utils/filterProjectPath.js +7 -2
- package/dist/utils/oraWrapper.js +5 -1
- package/package.json +13 -9
- package/src/audit/autodetection/autoDetectLanguage.ts +3 -3
- package/src/audit/catalogueApplication/catalogueApplication.js +28 -7
- package/src/audit/javaAnalysisEngine/parseMavenProjectFileContents.js +11 -8
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedLanguages.js +2 -1
- package/src/audit/languageAnalysisEngine/checkForMultipleIdentifiedProjectFiles.js +2 -1
- package/src/audit/languageAnalysisEngine/checkIdentifiedLanguageHasProjectFile.js +2 -1
- package/src/audit/languageAnalysisEngine/getIdentifiedLanguageInfo.js +5 -5
- package/src/audit/languageAnalysisEngine/getProjectRootFilenames.js +11 -11
- package/src/audit/languageAnalysisEngine/index.js +2 -2
- package/src/audit/languageAnalysisEngine/languageAnalysisFactory.js +11 -31
- package/src/audit/languageAnalysisEngine/reduceIdentifiedLanguages.js +35 -32
- package/src/audit/languageAnalysisEngine/report/commonReportingFunctions.ts +179 -25
- package/src/audit/languageAnalysisEngine/report/models/reportLibraryModel.ts +3 -3
- package/src/audit/languageAnalysisEngine/report/models/reportListModel.ts +18 -11
- package/src/audit/languageAnalysisEngine/report/models/reportOutputModel.ts +29 -0
- package/src/audit/languageAnalysisEngine/report/models/reportSeverityModel.ts +12 -3
- package/src/audit/languageAnalysisEngine/report/models/severityCountModel.ts +20 -0
- package/src/audit/languageAnalysisEngine/report/reportingFeature.ts +50 -18
- package/src/audit/languageAnalysisEngine/report/utils/reportUtils.ts +88 -66
- package/src/audit/languageAnalysisEngine/sendSnapshot.js +78 -3
- package/src/audit/save.js +32 -0
- package/src/commands/audit/auditController.ts +23 -15
- package/src/commands/audit/help.ts +24 -1
- package/src/commands/audit/processAudit.ts +7 -4
- package/src/commands/audit/saveFile.ts +5 -1
- package/src/commands/scan/processScan.js +2 -1
- package/src/commands/scan/sca/scaAnalysis.js +70 -29
- package/src/common/HTTPClient.js +72 -25
- package/src/common/errorHandling.ts +10 -1
- package/src/common/versionChecker.ts +24 -5
- package/src/constants/constants.js +13 -3
- package/src/constants/locales.js +15 -12
- package/src/constants.js +9 -4
- package/src/index.ts +5 -3
- package/src/lambda/analytics.ts +9 -0
- package/src/lambda/arn.ts +2 -1
- package/src/lambda/lambda.ts +37 -17
- package/src/lambda/types.ts +35 -0
- package/src/lambda/utils.ts +2 -7
- package/src/sbom/generateSbom.ts +1 -1
- package/src/scaAnalysis/common/formatMessage.js +51 -1
- package/src/scaAnalysis/common/treeUpload.js +1 -6
- package/src/scaAnalysis/go/goAnalysis.js +19 -0
- package/src/scaAnalysis/go/goParseDeps.js +203 -0
- package/src/scaAnalysis/go/goReadDepFile.js +30 -0
- package/src/scaAnalysis/java/analysis.js +15 -32
- package/src/scaAnalysis/java/index.js +6 -6
- package/src/scaAnalysis/java/javaBuildDepsParser.js +15 -2
- package/src/scaAnalysis/javascript/analysis.js +127 -0
- package/src/scaAnalysis/javascript/index.js +56 -0
- package/src/scaAnalysis/php/analysis.js +98 -0
- package/src/scaAnalysis/php/index.js +11 -0
- package/src/scaAnalysis/python/analysis.js +49 -0
- package/src/scaAnalysis/python/index.js +11 -0
- package/src/scaAnalysis/ruby/analysis.js +282 -0
- package/src/scaAnalysis/ruby/index.js +11 -0
- package/src/scan/autoDetection.js +11 -7
- package/src/scan/fileUtils.js +27 -8
- package/src/scan/formatScanOutput.ts +26 -18
- package/src/scan/models/groupedResultsModel.ts +3 -3
- package/src/scan/models/resultContentModel.ts +1 -1
- package/src/scan/models/scanResultsModel.ts +5 -2
- package/src/scan/populateProjectIdAndProjectName.js +3 -1
- package/src/scan/scan.ts +8 -6
- package/src/scan/scanConfig.js +5 -1
- package/src/scan/scanController.js +30 -9
- package/src/scan/scanResults.js +31 -10
- package/src/utils/commonApi.js +4 -1
- package/src/utils/filterProjectPath.js +6 -2
- package/src/utils/oraWrapper.js +6 -1
package/.prettierignore
CHANGED
|
@@ -8,14 +8,14 @@ const i18n_1 = __importDefault(require("i18n"));
|
|
|
8
8
|
const reduceIdentifiedLanguages_1 = require("../languageAnalysisEngine/reduceIdentifiedLanguages");
|
|
9
9
|
const getProjectRootFilenames_1 = require("../languageAnalysisEngine/getProjectRootFilenames");
|
|
10
10
|
function identifyLanguages(config) {
|
|
11
|
-
const {
|
|
12
|
-
const projectRootFilenames = (0, getProjectRootFilenames_1.getProjectRootFilenames)(
|
|
11
|
+
const { file } = config;
|
|
12
|
+
const projectRootFilenames = (0, getProjectRootFilenames_1.getProjectRootFilenames)(file);
|
|
13
13
|
const identifiedLanguages = projectRootFilenames.reduce((accumulator, filename) => {
|
|
14
14
|
const deducedLanguages = (0, reduceIdentifiedLanguages_1.deduceLanguage)(filename);
|
|
15
15
|
return [...accumulator, ...deducedLanguages];
|
|
16
16
|
}, []);
|
|
17
17
|
if (Object.keys(identifiedLanguages).length === 0) {
|
|
18
|
-
throw new Error(i18n_1.default.__('languageAnalysisNoLanguage',
|
|
18
|
+
throw new Error(i18n_1.default.__('languageAnalysisNoLanguage', file));
|
|
19
19
|
}
|
|
20
20
|
return (0, reduceIdentifiedLanguages_1.reduceIdentifiedLanguages)(identifiedLanguages);
|
|
21
21
|
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const i18n = require('i18n');
|
|
3
2
|
const { getHttpClient, handleResponseErrors } = require('../../utils/commonApi');
|
|
4
|
-
const displaySuccessMessage = () => {
|
|
5
|
-
console.log(i18n.__('catalogueSuccessCommand'));
|
|
6
|
-
};
|
|
7
3
|
const catalogueApplication = async (config) => {
|
|
8
4
|
const client = getHttpClient(config);
|
|
9
5
|
let appId;
|
|
@@ -13,6 +9,9 @@ const catalogueApplication = async (config) => {
|
|
|
13
9
|
if (res.statusCode === 201) {
|
|
14
10
|
appId = res.body.application.app_id;
|
|
15
11
|
}
|
|
12
|
+
else if (doesMessagesContainAppId(res)) {
|
|
13
|
+
appId = tryRetrieveAppIdFromMessages(res.body.messages);
|
|
14
|
+
}
|
|
16
15
|
else {
|
|
17
16
|
handleResponseErrors(res, 'catalogue');
|
|
18
17
|
}
|
|
@@ -22,6 +21,25 @@ const catalogueApplication = async (config) => {
|
|
|
22
21
|
});
|
|
23
22
|
return appId;
|
|
24
23
|
};
|
|
24
|
+
const doesMessagesContainAppId = res => {
|
|
25
|
+
const regex = /(Application ID =)/;
|
|
26
|
+
if (res.statusCode === 400 &&
|
|
27
|
+
res.body.messages.filter(message => regex.exec(message))[0]) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
};
|
|
32
|
+
const tryRetrieveAppIdFromMessages = messages => {
|
|
33
|
+
let appId;
|
|
34
|
+
messages.forEach(message => {
|
|
35
|
+
if (message.includes('Application ID')) {
|
|
36
|
+
appId = message.split('=')[1].replace(/\s+/g, '');
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return appId;
|
|
40
|
+
};
|
|
25
41
|
module.exports = {
|
|
26
|
-
catalogueApplication: catalogueApplication
|
|
42
|
+
catalogueApplication: catalogueApplication,
|
|
43
|
+
doesMessagesContainAppId,
|
|
44
|
+
tryRetrieveAppIdFromMessages
|
|
27
45
|
};
|
|
@@ -142,10 +142,12 @@ const parseMvn = mvnDependancyTreeOutput => {
|
|
|
142
142
|
});
|
|
143
143
|
return parsedDepObj;
|
|
144
144
|
};
|
|
145
|
-
exports.shaveConsoleOutputUntilItFindsFirsDigraphMention =
|
|
145
|
+
exports.shaveConsoleOutputUntilItFindsFirsDigraphMention =
|
|
146
|
+
shaveConsoleOutputUntilItFindsFirsDigraphMention;
|
|
146
147
|
exports.getDigraphObjInfo = getDigraphObjInfo;
|
|
147
148
|
exports.createDigraphObjKey = createDigraphObjKey;
|
|
148
|
-
exports.turnDigraphDependanciesIntoArrOfInnerDep =
|
|
149
|
+
exports.turnDigraphDependanciesIntoArrOfInnerDep =
|
|
150
|
+
turnDigraphDependanciesIntoArrOfInnerDep;
|
|
149
151
|
exports.hasVersion = hasVersion;
|
|
150
152
|
exports.formatKeyName = formatKeyName;
|
|
151
153
|
exports.createOuterDependanciesAndType = createOuterDependanciesAndType;
|
|
@@ -21,4 +21,5 @@ const checkForMultipleIdentifiedLanguages = identifiedLanguages => {
|
|
|
21
21
|
throw new Error(errMsg);
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
-
exports.checkForMultipleIdentifiedLanguages =
|
|
24
|
+
exports.checkForMultipleIdentifiedLanguages =
|
|
25
|
+
checkForMultipleIdentifiedLanguages;
|
|
@@ -21,4 +21,5 @@ const checkForMultipleIdentifiedProjectFiles = identifiedLanguages => {
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
-
exports.checkForMultipleIdentifiedProjectFiles =
|
|
24
|
+
exports.checkForMultipleIdentifiedProjectFiles =
|
|
25
|
+
checkForMultipleIdentifiedProjectFiles;
|
|
@@ -20,4 +20,5 @@ const checkIdentifiedLanguageHasProjectFile = identifiedLanguages => {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
-
exports.checkIdentifiedLanguageHasProjectFile =
|
|
23
|
+
exports.checkIdentifiedLanguageHasProjectFile =
|
|
24
|
+
checkIdentifiedLanguageHasProjectFile;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const path = require('path');
|
|
3
3
|
module.exports = exports = (analysis, next) => {
|
|
4
|
-
const {
|
|
5
|
-
languageAnalysis.identifiedLanguageInfo = getIdentifiedLanguageInfo(
|
|
4
|
+
const { file, languageAnalysis } = analysis;
|
|
5
|
+
languageAnalysis.identifiedLanguageInfo = getIdentifiedLanguageInfo(file, languageAnalysis.identifiedLanguages);
|
|
6
6
|
next();
|
|
7
7
|
};
|
|
8
|
-
const getIdentifiedLanguageInfo = (
|
|
8
|
+
const getIdentifiedLanguageInfo = (file, identifiedLanguages) => {
|
|
9
9
|
const [language] = Object.keys(identifiedLanguages);
|
|
10
10
|
const { projectFilenames: [projectFilename], lockFilenames: [lockFilename] } = Object.values(identifiedLanguages)[0];
|
|
11
11
|
let identifiedLanguageInfo = {
|
|
12
12
|
language,
|
|
13
13
|
projectFilename,
|
|
14
|
-
projectFilePath: path.join(
|
|
14
|
+
projectFilePath: path.join(file, projectFilename)
|
|
15
15
|
};
|
|
16
16
|
if (lockFilename) {
|
|
17
17
|
identifiedLanguageInfo = {
|
|
18
18
|
...identifiedLanguageInfo,
|
|
19
19
|
lockFilename,
|
|
20
|
-
lockFilePath: path.join(
|
|
20
|
+
lockFilePath: path.join(file, lockFilename)
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
return identifiedLanguageInfo;
|
|
@@ -3,9 +3,9 @@ const fs = require('fs');
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const i18n = require('i18n');
|
|
5
5
|
module.exports = exports = (analysis, next) => {
|
|
6
|
-
const {
|
|
6
|
+
const { file, languageAnalysis } = analysis;
|
|
7
7
|
try {
|
|
8
|
-
languageAnalysis.projectRootFilenames = getProjectRootFilenames(
|
|
8
|
+
languageAnalysis.projectRootFilenames = getProjectRootFilenames(file);
|
|
9
9
|
}
|
|
10
10
|
catch (err) {
|
|
11
11
|
next(err);
|
|
@@ -13,27 +13,27 @@ module.exports = exports = (analysis, next) => {
|
|
|
13
13
|
}
|
|
14
14
|
next();
|
|
15
15
|
};
|
|
16
|
-
const getProjectRootFilenames =
|
|
16
|
+
const getProjectRootFilenames = file => {
|
|
17
17
|
let projectStats = null;
|
|
18
18
|
try {
|
|
19
|
-
projectStats = fs.statSync(
|
|
19
|
+
projectStats = fs.statSync(file);
|
|
20
20
|
}
|
|
21
21
|
catch (err) {
|
|
22
|
-
throw new Error(i18n.__('languageAnalysisProjectRootFileNameFailure',
|
|
22
|
+
throw new Error(i18n.__('languageAnalysisProjectRootFileNameFailure', file) +
|
|
23
23
|
`${err.message}`);
|
|
24
24
|
}
|
|
25
25
|
if (projectStats.isDirectory()) {
|
|
26
26
|
try {
|
|
27
|
-
return fs.readdirSync(
|
|
27
|
+
return fs.readdirSync(file);
|
|
28
28
|
}
|
|
29
29
|
catch (err) {
|
|
30
|
-
throw new Error(i18n.__('languageAnalysisProjectRootFileNameReadError',
|
|
30
|
+
throw new Error(i18n.__('languageAnalysisProjectRootFileNameReadError', file) +
|
|
31
31
|
`${err.message}`);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
if (projectStats.isFile()) {
|
|
35
|
-
return [path.basename(
|
|
35
|
+
return [path.basename(file)];
|
|
36
36
|
}
|
|
37
|
-
throw new Error(i18n.__('languageAnalysisProjectRootFileNameMissingError'),
|
|
37
|
+
throw new Error(i18n.__('languageAnalysisProjectRootFileNameMissingError'), file);
|
|
38
38
|
};
|
|
39
39
|
exports.getProjectRootFilenames = getProjectRootFilenames;
|
|
@@ -9,9 +9,9 @@ const checkIdentifiedLanguageHasProjectFile = require('./checkIdentifiedLanguage
|
|
|
9
9
|
const checkIdentifiedLanguageHasLockFile = require('./checkIdentifiedLanguageHasLockFile');
|
|
10
10
|
const getIdentifiedLanguageInfo = require('./getIdentifiedLanguageInfo');
|
|
11
11
|
const { libraryAnalysisError } = require('../../common/errorHandling');
|
|
12
|
-
module.exports = exports = (
|
|
12
|
+
module.exports = exports = (file, callback, appId, config) => {
|
|
13
13
|
const ae = new AnalysisEngine({
|
|
14
|
-
|
|
14
|
+
file,
|
|
15
15
|
appId,
|
|
16
16
|
languageAnalysis: { appId: appId },
|
|
17
17
|
config
|
|
@@ -10,11 +10,9 @@ const phpAE = require('../phpAnalysisEngine');
|
|
|
10
10
|
const goAE = require('../goAnalysisEngine');
|
|
11
11
|
const { vulnerabilityReport } = require('./report/reportingFeature');
|
|
12
12
|
const { newSendSnapShot } = require('../languageAnalysisEngine/sendSnapshot');
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const generateSbom = require('../../sbom/generateSbom').default;
|
|
17
|
-
const { failSpinner, returnOra, startSpinner, succeedSpinner } = require('../../utils/oraWrapper');
|
|
13
|
+
const { returnOra, startSpinner, succeedSpinner } = require('../../utils/oraWrapper');
|
|
14
|
+
const { pollForSnapshotCompletition } = require('./sendSnapshot');
|
|
15
|
+
const auditSave = require('../save');
|
|
18
16
|
module.exports = exports = (err, analysis) => {
|
|
19
17
|
const { identifiedLanguageInfo } = analysis.languageAnalysis;
|
|
20
18
|
const catalogueAppId = analysis.languageAnalysis.appId;
|
|
@@ -39,9 +37,10 @@ module.exports = exports = (err, analysis) => {
|
|
|
39
37
|
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'));
|
|
40
38
|
startSpinner(reportSpinner);
|
|
41
39
|
const snapshotResponse = await newSendSnapShot(analysis, catalogueAppId);
|
|
42
|
-
|
|
40
|
+
await pollForSnapshotCompletition(analysis.config, snapshotResponse.id, reportSpinner);
|
|
41
|
+
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'));
|
|
43
42
|
await vulnerabilityReport(analysis, catalogueAppId, snapshotResponse.id);
|
|
44
|
-
await auditSave(config);
|
|
43
|
+
await auditSave.auditSave(config);
|
|
45
44
|
};
|
|
46
45
|
if (identifiedLanguageInfo.language === DOTNET) {
|
|
47
46
|
dotnetAE(identifiedLanguageInfo, analysis.config, langCallback);
|
|
@@ -65,23 +64,3 @@ module.exports = exports = (err, analysis) => {
|
|
|
65
64
|
goAE(identifiedLanguageInfo, analysis.config, langCallback);
|
|
66
65
|
}
|
|
67
66
|
};
|
|
68
|
-
async function auditSave(config) {
|
|
69
|
-
if (config.save) {
|
|
70
|
-
if (config.save.toLowerCase() === 'sbom') {
|
|
71
|
-
saveFile(config, await generateSbom(config));
|
|
72
|
-
const filename = `${config.applicationId}-sbom-cyclonedx.json`;
|
|
73
|
-
if (fs.existsSync(filename)) {
|
|
74
|
-
console.log(i18n.__('auditSBOMSaveSuccess') + ` - ${filename}`);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
console.log(chalk.yellow.bold(`\n Unable to save ${filename} Software Bill of Materials (SBOM)`));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
console.log(i18n.__('auditBadFiletypeSpecifiedForSave'));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
else if (config.save === null) {
|
|
85
|
-
console.log(i18n.__('auditNoFiletypeSpecifiedForSave'));
|
|
86
|
-
}
|
|
87
|
-
}
|
|
@@ -36,11 +36,30 @@ const deduceLanguageScaAnalysis = filenames => {
|
|
|
36
36
|
}
|
|
37
37
|
if (isNodeProjectFilename(filename)) {
|
|
38
38
|
deducedLanguages.push(filename);
|
|
39
|
-
language =
|
|
39
|
+
language = JAVASCRIPT;
|
|
40
|
+
}
|
|
41
|
+
if (isRubyProjectFilename(filename)) {
|
|
42
|
+
deducedLanguages.push(filename);
|
|
43
|
+
language = RUBY;
|
|
44
|
+
}
|
|
45
|
+
if (isPythonProjectFilename(filename)) {
|
|
46
|
+
deducedLanguages.push(filename);
|
|
47
|
+
language = PYTHON;
|
|
48
|
+
}
|
|
49
|
+
if (isPhpProjectFilename(filename)) {
|
|
50
|
+
deducedLanguages.push({ language: PHP, projectFilename: filename });
|
|
51
|
+
language = PHP;
|
|
40
52
|
}
|
|
41
53
|
if (isNodeLockFilename(filename)) {
|
|
42
54
|
deducedLanguages.push(filename);
|
|
43
|
-
language =
|
|
55
|
+
language = JAVASCRIPT;
|
|
56
|
+
}
|
|
57
|
+
if (isPhpLockFilename(filename)) {
|
|
58
|
+
deducedLanguages.push({ language: PHP, lockFilename: filename });
|
|
59
|
+
}
|
|
60
|
+
if (isGoProjectFilename(filename)) {
|
|
61
|
+
deducedLanguages.push({ language: GO, projectFilename: filename });
|
|
62
|
+
language = GO;
|
|
44
63
|
}
|
|
45
64
|
});
|
|
46
65
|
let identifiedLanguages = { [language]: deducedLanguages };
|
|
@@ -103,18 +122,19 @@ const reduceIdentifiedLanguages = identifiedLanguages => identifiedLanguages.red
|
|
|
103
122
|
return accumulator;
|
|
104
123
|
}, {});
|
|
105
124
|
module.exports = exports = (analysis, next) => {
|
|
106
|
-
const {
|
|
125
|
+
const { file, languageAnalysis, config } = analysis;
|
|
107
126
|
let identifiedLanguages = languageAnalysis.projectRootFilenames.reduce((accumulator, filename) => {
|
|
108
127
|
const deducedLanguages = deduceLanguage(filename);
|
|
109
128
|
return [...accumulator, ...deducedLanguages];
|
|
110
129
|
}, []);
|
|
111
130
|
if (Object.keys(identifiedLanguages).length === 0) {
|
|
112
|
-
next(new Error(i18n.__('languageAnalysisNoLanguage',
|
|
131
|
+
next(new Error(i18n.__('languageAnalysisNoLanguage', file)));
|
|
113
132
|
return;
|
|
114
133
|
}
|
|
115
134
|
let language = config.language;
|
|
116
135
|
if (language === undefined) {
|
|
117
|
-
languageAnalysis.identifiedLanguages =
|
|
136
|
+
languageAnalysis.identifiedLanguages =
|
|
137
|
+
reduceIdentifiedLanguages(identifiedLanguages);
|
|
118
138
|
}
|
|
119
139
|
else {
|
|
120
140
|
let refinedIdentifiedLanguages = [];
|
|
@@ -3,16 +3,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.printFormattedOutput = exports.printVulnerabilityResponse = exports.getReport = exports.createLibraryHeader = void 0;
|
|
6
|
+
exports.getNumOfAndSeverityType = exports.buildFormattedHeaderNum = exports.buildBody = exports.buildHeader = exports.printFormattedOutput = exports.printVulnerabilityResponse = exports.getReport = exports.createLibraryHeader = void 0;
|
|
7
7
|
const commonApi_1 = require("../../../utils/commonApi");
|
|
8
8
|
const reportListModel_1 = require("./models/reportListModel");
|
|
9
9
|
const lodash_1 = require("lodash");
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
11
|
const reportUtils_1 = require("./utils/reportUtils");
|
|
12
|
+
const severityCountModel_1 = require("./models/severityCountModel");
|
|
13
|
+
const reportOutputModel_1 = require("./models/reportOutputModel");
|
|
14
|
+
const constants_1 = require("../../../constants/constants");
|
|
12
15
|
const createLibraryHeader = (id, numberOfVulnerableLibraries, numberOfCves) => {
|
|
13
16
|
numberOfVulnerableLibraries === 1
|
|
14
|
-
? console.log(`
|
|
15
|
-
: console.log(`
|
|
17
|
+
? console.log(`Found 1 vulnerable library containing ${numberOfCves} CVEs`)
|
|
18
|
+
: console.log(`Found ${numberOfVulnerableLibraries} vulnerable libraries containing ${numberOfCves} CVEs `);
|
|
16
19
|
};
|
|
17
20
|
exports.createLibraryHeader = createLibraryHeader;
|
|
18
21
|
const getReport = async (config, reportId) => {
|
|
@@ -24,10 +27,6 @@ const getReport = async (config, reportId) => {
|
|
|
24
27
|
return res.body;
|
|
25
28
|
}
|
|
26
29
|
else {
|
|
27
|
-
console.log('config-------------------');
|
|
28
|
-
console.log(config);
|
|
29
|
-
console.log('reportId----------------');
|
|
30
|
-
console.log(reportId);
|
|
31
30
|
console.log(JSON.stringify(res));
|
|
32
31
|
(0, commonApi_1.handleResponseErrors)(res, 'report');
|
|
33
32
|
}
|
|
@@ -50,22 +49,102 @@ const printFormattedOutput = (libraries, config) => {
|
|
|
50
49
|
const report = new reportListModel_1.ReportList();
|
|
51
50
|
for (const library of libraries) {
|
|
52
51
|
const { name, version } = (0, reportUtils_1.findNameAndVersion)(library, config);
|
|
53
|
-
const newOutputModel = new reportListModel_1.ReportModelStructure(new reportListModel_1.ReportCompositeKey(name, version, (0, reportUtils_1.findHighestSeverityCVE)(library.cveArray)), library.cveArray);
|
|
52
|
+
const newOutputModel = new reportListModel_1.ReportModelStructure(new reportListModel_1.ReportCompositeKey(name, version, (0, reportUtils_1.findHighestSeverityCVE)(library.cveArray), (0, reportUtils_1.severityCountAllCVEs)(library.cveArray, new severityCountModel_1.SeverityCountModel()).getTotal), library.cveArray);
|
|
54
53
|
report.reportOutputList.push(newOutputModel);
|
|
55
54
|
}
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = (0, lodash_1.orderBy)(report.reportOutputList, [
|
|
56
|
+
(reportListItem) => {
|
|
57
|
+
return reportListItem.compositeKey.highestSeverity.priority;
|
|
58
|
+
},
|
|
59
|
+
(reportListItem) => {
|
|
60
|
+
return reportListItem.compositeKey.numberOfSeverities;
|
|
61
|
+
}
|
|
62
|
+
], ['desc']);
|
|
63
|
+
let contrastHeaderNumCounter = outputOrderedByLowestSeverityAndLowestNumOfCvesFirst.length + 1;
|
|
64
|
+
for (const reportModel of outputOrderedByLowestSeverityAndLowestNumOfCvesFirst) {
|
|
65
|
+
contrastHeaderNumCounter--;
|
|
66
|
+
const { libraryName, libraryVersion, highestSeverity } = reportModel.compositeKey;
|
|
61
67
|
const numOfCVEs = reportModel.cveArray.length;
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
console.log(
|
|
67
|
-
console.log(
|
|
68
|
-
|
|
68
|
+
const header = buildHeader(highestSeverity, contrastHeaderNumCounter, libraryName, libraryVersion, numOfCVEs);
|
|
69
|
+
const body = buildBody(reportModel.cveArray);
|
|
70
|
+
const reportOutputModel = new reportOutputModel_1.ReportOutputModel(header, body);
|
|
71
|
+
console.log(reportOutputModel.header.vulnMessage, reportOutputModel.header.introducesMessage);
|
|
72
|
+
console.log(reportOutputModel.body.issueMessage);
|
|
73
|
+
console.log(reportOutputModel.body.adviceMessage + '\n');
|
|
74
|
+
}
|
|
75
|
+
const { criticalMessage, highMessage, mediumMessage, lowMessage, noteMessage, total } = buildFooter(libraries);
|
|
76
|
+
if (total > 1) {
|
|
77
|
+
console.log(`${criticalMessage} | ${highMessage} | ${mediumMessage} | ${lowMessage} | ${noteMessage}`);
|
|
69
78
|
}
|
|
70
79
|
};
|
|
71
80
|
exports.printFormattedOutput = printFormattedOutput;
|
|
81
|
+
function buildHeader(highestSeverity, contrastHeaderNum, libraryName, version, numOfCVEs) {
|
|
82
|
+
const vulnerabilityPluralised = numOfCVEs > 1 ? 'vulnerabilities' : 'vulnerability';
|
|
83
|
+
const formattedHeaderNum = buildFormattedHeaderNum(contrastHeaderNum);
|
|
84
|
+
const vulnMessage = chalk_1.default
|
|
85
|
+
.hex(highestSeverity.outputColour)
|
|
86
|
+
.bold(`${formattedHeaderNum} - [${highestSeverity.severity}] ${libraryName}-${version}`);
|
|
87
|
+
const introducesMessage = chalk_1.default.bold(`introduces ${numOfCVEs} ${vulnerabilityPluralised}`);
|
|
88
|
+
return new reportOutputModel_1.ReportOutputHeaderModel(vulnMessage, introducesMessage);
|
|
89
|
+
}
|
|
90
|
+
exports.buildHeader = buildHeader;
|
|
91
|
+
function buildBody(cveArray) {
|
|
92
|
+
const cveMessages = [];
|
|
93
|
+
(0, reportUtils_1.findCVESeveritiesAndOrderByHighestPriority)(cveArray).forEach(reportSeverityModel => {
|
|
94
|
+
const { outputColour, severity, cveName } = reportSeverityModel;
|
|
95
|
+
const severityShorthand = chalk_1.default
|
|
96
|
+
.hex(outputColour)
|
|
97
|
+
.bold(`[${severity.charAt(0).toUpperCase()}]`);
|
|
98
|
+
const builtMessage = `${severityShorthand} ${cveName}`;
|
|
99
|
+
cveMessages.push(builtMessage);
|
|
100
|
+
});
|
|
101
|
+
const numAndSeverityType = getNumOfAndSeverityType(cveArray);
|
|
102
|
+
const issueMessage = ` ${chalk_1.default.bold('Issue')} : ${numAndSeverityType} ${cveMessages.join(', ')}.`;
|
|
103
|
+
const adviceMessage = ` ${chalk_1.default.bold('Advice')} : ${chalk_1.default.bold('Update to latest version')}.`;
|
|
104
|
+
return new reportOutputModel_1.ReportOutputBodyModel(issueMessage, adviceMessage);
|
|
105
|
+
}
|
|
106
|
+
exports.buildBody = buildBody;
|
|
107
|
+
const buildFooter = (libraries) => {
|
|
108
|
+
const { critical, high, medium, low, note, getTotal } = (0, reportUtils_1.severityCountAllLibraries)(libraries);
|
|
109
|
+
const criticalMessage = chalk_1.default
|
|
110
|
+
.hex(constants_1.CRITICAL_COLOUR)
|
|
111
|
+
.bold(`${critical} Critical`);
|
|
112
|
+
const highMessage = chalk_1.default.hex(constants_1.HIGH_COLOUR).bold(`${high} High`);
|
|
113
|
+
const mediumMessage = chalk_1.default.hex(constants_1.MEDIUM_COLOUR).bold(`${medium} Medium`);
|
|
114
|
+
const lowMessage = chalk_1.default.hex(constants_1.LOW_COLOUR).bold(`${low} Low`);
|
|
115
|
+
const noteMessage = chalk_1.default.hex(constants_1.NOTE_COLOUR).bold(`${note} Note`);
|
|
116
|
+
return {
|
|
117
|
+
criticalMessage,
|
|
118
|
+
highMessage,
|
|
119
|
+
mediumMessage,
|
|
120
|
+
lowMessage,
|
|
121
|
+
noteMessage,
|
|
122
|
+
total: getTotal
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
function buildFormattedHeaderNum(contrastHeaderNum) {
|
|
126
|
+
let formattedHeaderNum;
|
|
127
|
+
if (contrastHeaderNum < 10) {
|
|
128
|
+
formattedHeaderNum = `00${contrastHeaderNum}`;
|
|
129
|
+
}
|
|
130
|
+
else if (contrastHeaderNum >= 10 && contrastHeaderNum < 100) {
|
|
131
|
+
formattedHeaderNum = `0${contrastHeaderNum}`;
|
|
132
|
+
}
|
|
133
|
+
else if (contrastHeaderNum >= 100) {
|
|
134
|
+
formattedHeaderNum = contrastHeaderNum;
|
|
135
|
+
}
|
|
136
|
+
return `CONTRAST-${formattedHeaderNum}`;
|
|
137
|
+
}
|
|
138
|
+
exports.buildFormattedHeaderNum = buildFormattedHeaderNum;
|
|
139
|
+
function getNumOfAndSeverityType(cveArray) {
|
|
140
|
+
const { critical, high, medium, low, note } = (0, reportUtils_1.severityCountAllCVEs)(cveArray, new severityCountModel_1.SeverityCountModel());
|
|
141
|
+
const criticalMessage = critical > 0 ? `${critical} Critical` : '';
|
|
142
|
+
const highMessage = high > 0 ? `${high} High` : '';
|
|
143
|
+
const mediumMessage = medium > 0 ? `${medium} Medium` : '';
|
|
144
|
+
const lowMessage = low > 0 ? `${low} Low` : '';
|
|
145
|
+
const noteMessage = note > 0 ? `${note} Note` : '';
|
|
146
|
+
return `${criticalMessage} ${highMessage} ${mediumMessage} ${lowMessage} ${noteMessage}`
|
|
147
|
+
.replace(/\s+/g, ' ')
|
|
148
|
+
.trim();
|
|
149
|
+
}
|
|
150
|
+
exports.getNumOfAndSeverityType = getNumOfAndSeverityType;
|
|
@@ -15,10 +15,11 @@ class ReportModelStructure {
|
|
|
15
15
|
}
|
|
16
16
|
exports.ReportModelStructure = ReportModelStructure;
|
|
17
17
|
class ReportCompositeKey {
|
|
18
|
-
constructor(libraryName, libraryVersion, highestSeverity) {
|
|
18
|
+
constructor(libraryName, libraryVersion, highestSeverity, numberOfSeverities) {
|
|
19
19
|
this.libraryName = libraryName;
|
|
20
20
|
this.libraryVersion = libraryVersion;
|
|
21
21
|
this.highestSeverity = highestSeverity;
|
|
22
|
+
this.numberOfSeverities = numberOfSeverities;
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
exports.ReportCompositeKey = ReportCompositeKey;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ReportOutputBodyModel = exports.ReportOutputHeaderModel = exports.ReportOutputModel = void 0;
|
|
4
|
+
class ReportOutputModel {
|
|
5
|
+
constructor(header, body) {
|
|
6
|
+
this.header = header;
|
|
7
|
+
this.body = body;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.ReportOutputModel = ReportOutputModel;
|
|
11
|
+
class ReportOutputHeaderModel {
|
|
12
|
+
constructor(vulnMessage, introducesMessage) {
|
|
13
|
+
this.vulnMessage = vulnMessage;
|
|
14
|
+
this.introducesMessage = introducesMessage;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.ReportOutputHeaderModel = ReportOutputHeaderModel;
|
|
18
|
+
class ReportOutputBodyModel {
|
|
19
|
+
constructor(bodyIssueMessage, bodyAdviceMessage) {
|
|
20
|
+
this.issueMessage = bodyIssueMessage;
|
|
21
|
+
this.adviceMessage = bodyAdviceMessage;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ReportOutputBodyModel = ReportOutputBodyModel;
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ReportSeverityModel = void 0;
|
|
4
4
|
class ReportSeverityModel {
|
|
5
|
-
constructor(severity, priority) {
|
|
5
|
+
constructor(severity, priority, outputColour, cveName) {
|
|
6
6
|
this.severity = severity;
|
|
7
7
|
this.priority = priority;
|
|
8
|
+
this.outputColour = outputColour;
|
|
9
|
+
this.cveName = cveName;
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
12
|
exports.ReportSeverityModel = ReportSeverityModel;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SeverityCountModel = void 0;
|
|
4
|
+
class SeverityCountModel {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.critical = 0;
|
|
7
|
+
this.high = 0;
|
|
8
|
+
this.medium = 0;
|
|
9
|
+
this.low = 0;
|
|
10
|
+
this.note = 0;
|
|
11
|
+
}
|
|
12
|
+
get getTotal() {
|
|
13
|
+
return this.critical + this.high + this.medium + this.low + this.note;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.SeverityCountModel = SeverityCountModel;
|
|
@@ -1,28 +1,49 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.formatVulnerabilityOutput = exports.vulnerabilityReport = void 0;
|
|
6
|
+
exports.vulnerabilityReportV2 = exports.formatVulnerabilityOutput = exports.vulnerabilityReport = void 0;
|
|
4
7
|
const commonReportingFunctions_1 = require("./commonReportingFunctions");
|
|
5
8
|
const reportUtils_1 = require("./utils/reportUtils");
|
|
9
|
+
const i18n_1 = __importDefault(require("i18n"));
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
6
11
|
async function vulnerabilityReport(analysis, applicationId, reportId) {
|
|
7
12
|
const reportResponse = await (0, commonReportingFunctions_1.getReport)(analysis.config, reportId);
|
|
8
13
|
if (reportResponse !== undefined) {
|
|
9
14
|
const id = applicationId;
|
|
10
|
-
|
|
11
|
-
formatVulnerabilityOutput(reportResponse.vulnerabilities, id, name, analysis.config);
|
|
15
|
+
formatVulnerabilityOutput(reportResponse.vulnerabilities, id, analysis.config);
|
|
12
16
|
}
|
|
13
17
|
}
|
|
14
18
|
exports.vulnerabilityReport = vulnerabilityReport;
|
|
15
|
-
function formatVulnerabilityOutput(libraryVulnerabilityResponse, id,
|
|
16
|
-
const vulnerableLibraries = (0, reportUtils_1.
|
|
19
|
+
function formatVulnerabilityOutput(libraryVulnerabilityResponse, id, config) {
|
|
20
|
+
const vulnerableLibraries = (0, reportUtils_1.convertGenericToTypedLibraryVulns)(libraryVulnerabilityResponse);
|
|
17
21
|
const numberOfVulnerableLibraries = vulnerableLibraries.length;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
if (numberOfVulnerableLibraries === 0) {
|
|
23
|
+
console.log(i18n_1.default.__('scanNoVulnerabilitiesFound'));
|
|
24
|
+
console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundSecureCode'));
|
|
25
|
+
console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundGoodWork'));
|
|
26
|
+
console.log(chalk_1.default.bold(`Found ${numberOfVulnerableLibraries} vulnerabilities`));
|
|
27
|
+
console.log(i18n_1.default.__('foundDetailedVulnerabilities', String(0), String(0), String(0), String(0), String(0)));
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
let numberOfCves = 0;
|
|
31
|
+
vulnerableLibraries.forEach(lib => (numberOfCves += lib.cveArray.length));
|
|
32
|
+
(0, commonReportingFunctions_1.createLibraryHeader)(id, numberOfVulnerableLibraries, numberOfCves);
|
|
33
|
+
const hasSomeVulnerabilitiesReported = (0, commonReportingFunctions_1.printVulnerabilityResponse)(vulnerableLibraries, config);
|
|
34
|
+
return [
|
|
35
|
+
hasSomeVulnerabilitiesReported,
|
|
36
|
+
numberOfCves,
|
|
37
|
+
(0, reportUtils_1.severityCountAllLibraries)(vulnerableLibraries)
|
|
38
|
+
];
|
|
39
|
+
}
|
|
27
40
|
}
|
|
28
41
|
exports.formatVulnerabilityOutput = formatVulnerabilityOutput;
|
|
42
|
+
async function vulnerabilityReportV2(config, reportId) {
|
|
43
|
+
const reportResponse = await (0, commonReportingFunctions_1.getReport)(config, reportId);
|
|
44
|
+
if (reportResponse !== undefined) {
|
|
45
|
+
const name = config.applicationName;
|
|
46
|
+
formatVulnerabilityOutput(reportResponse.vulnerabilities, config.applicationId, config);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.vulnerabilityReportV2 = vulnerabilityReportV2;
|