@contrast/contrast 1.0.19 → 1.0.20
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/dist/audit/report/commonReportingFunctions.js +3 -4
- package/dist/audit/report/models/reportListModel.js +2 -1
- package/dist/audit/report/reportingFeature.js +1 -1
- package/dist/audit/report/utils/reportUtils.js +30 -11
- package/dist/commands/audit/auditConfig.js +1 -2
- package/dist/commands/scan/sca/scaAnalysis.js +4 -2
- package/dist/constants/constants.js +1 -1
- package/dist/constants/locales.js +6 -2
- package/dist/scaAnalysis/common/auditReport.js +16 -60
- package/dist/scaAnalysis/common/commonReportingFunctionsSca.js +154 -0
- package/dist/scaAnalysis/common/models/ScaReportModel.js +45 -0
- package/dist/scaAnalysis/common/scaServicesUpload.js +4 -3
- package/dist/scaAnalysis/common/utils/reportUtilsSca.js +76 -0
- package/dist/scaAnalysis/java/analysis.js +1 -28
- package/dist/scaAnalysis/java/index.js +1 -13
- package/dist/scan/formatScanOutput.js +19 -13
- package/dist/utils/paramsUtil/configStoreParams.js +1 -12
- package/dist/utils/paramsUtil/paramHandler.js +1 -7
- package/package.json +5 -1
- package/src/audit/report/commonReportingFunctions.js +7 -5
- package/src/audit/report/models/reportListModel.ts +12 -2
- package/src/audit/report/reportingFeature.ts +1 -1
- package/src/audit/report/utils/reportUtils.ts +4 -4
- package/src/commands/audit/auditConfig.js +1 -2
- package/src/commands/scan/sca/scaAnalysis.js +7 -2
- package/src/constants/constants.js +1 -1
- package/src/constants/locales.js +6 -2
- package/src/scaAnalysis/common/auditReport.js +25 -80
- package/src/scaAnalysis/common/commonReportingFunctionsSca.js +276 -0
- package/src/scaAnalysis/common/models/ScaReportModel.ts +81 -0
- package/src/scaAnalysis/common/scaServicesUpload.js +5 -3
- package/src/scaAnalysis/common/utils/reportUtilsSca.ts +123 -0
- package/src/scaAnalysis/java/analysis.js +1 -28
- package/src/scaAnalysis/java/index.js +1 -18
- package/src/scan/formatScanOutput.ts +28 -17
- package/src/utils/getConfig.ts +0 -1
- package/src/utils/paramsUtil/configStoreParams.js +1 -14
- package/src/utils/paramsUtil/paramHandler.js +1 -9
|
@@ -3,13 +3,10 @@ const analysis = require('./analysis');
|
|
|
3
3
|
const { parseBuildDeps } = require('./javaBuildDepsParser');
|
|
4
4
|
const { createJavaTSMessage } = require('../common/formatMessage');
|
|
5
5
|
const { parseDependenciesForSCAServices } = require('../common/scaParserForGoAndJava');
|
|
6
|
-
const chalk = require('chalk');
|
|
7
|
-
const _ = require('lodash');
|
|
8
6
|
const javaAnalysis = async (config, languageFiles) => {
|
|
9
7
|
languageFiles.JAVA.forEach(file => {
|
|
10
8
|
file.replace('build.gradle.kts', 'build.gradle');
|
|
11
9
|
});
|
|
12
|
-
await getAgreement(config);
|
|
13
10
|
const javaDeps = buildJavaTree(config, languageFiles.JAVA);
|
|
14
11
|
if (config.experimental) {
|
|
15
12
|
return parseDependenciesForSCAServices(javaDeps);
|
|
@@ -18,19 +15,10 @@ const javaAnalysis = async (config, languageFiles) => {
|
|
|
18
15
|
return createJavaTSMessage(javaDeps);
|
|
19
16
|
}
|
|
20
17
|
};
|
|
21
|
-
const getAgreement = async (config) => {
|
|
22
|
-
console.log(chalk.bold('Java project detected'));
|
|
23
|
-
console.log('Java analysis uses maven / gradle which are potentially susceptible to command injection. Be sure that the code you are running Contrast CLI on is trusted before continuing.');
|
|
24
|
-
if (!process.env.CI && !config?.javaAgreement) {
|
|
25
|
-
return await analysis.agreementPrompt(config);
|
|
26
|
-
}
|
|
27
|
-
return config;
|
|
28
|
-
};
|
|
29
18
|
const buildJavaTree = (config, files) => {
|
|
30
19
|
const javaBuildDeps = analysis.getJavaBuildDeps(config, files);
|
|
31
20
|
return parseBuildDeps(config, javaBuildDeps);
|
|
32
21
|
};
|
|
33
22
|
module.exports = {
|
|
34
|
-
javaAnalysis
|
|
35
|
-
getAgreement
|
|
23
|
+
javaAnalysis
|
|
36
24
|
};
|
|
@@ -3,7 +3,7 @@ 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.assignBySeverity = exports.stripTags = exports.getCodeFlowInfo = exports.getSourceLineNumber = exports.getLocationsSyncInfo = exports.editVulName = exports.getDefaultView = exports.formatLinks = exports.formatScanOutput = void 0;
|
|
6
|
+
exports.assignBySeverity = exports.stripTags = exports.getCodeFlowInfo = exports.getSourceLineNumber = exports.getLocationsSyncInfo = exports.editVulName = exports.doAddSourceLineNumber = exports.getDefaultView = exports.formatLinks = exports.formatScanOutput = void 0;
|
|
7
7
|
const i18n_1 = __importDefault(require("i18n"));
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const groupedResultsModel_1 = require("./models/groupedResultsModel");
|
|
@@ -12,24 +12,25 @@ const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
|
12
12
|
const constants_1 = require("../constants/constants");
|
|
13
13
|
const commonReportingFunctions_1 = require("../audit/report/commonReportingFunctions");
|
|
14
14
|
function formatScanOutput(scanResults) {
|
|
15
|
-
const {
|
|
16
|
-
const
|
|
17
|
-
|
|
15
|
+
const { content } = scanResults.scanResultsInstances;
|
|
16
|
+
const { language } = scanResults.scanDetail;
|
|
17
|
+
const severityCounts = (0, commonReportingFunctions_1.getSeverityCounts)(content);
|
|
18
|
+
if (content.length === 0) {
|
|
18
19
|
console.log(i18n_1.default.__('scanNoVulnerabilitiesFound'));
|
|
19
20
|
console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundSecureCode'));
|
|
20
21
|
console.log(i18n_1.default.__('scanNoVulnerabilitiesFoundGoodWork'));
|
|
21
22
|
}
|
|
22
23
|
else {
|
|
23
|
-
const message =
|
|
24
|
+
const message = severityCounts.critical || severityCounts.high
|
|
24
25
|
? 'Here are your top priorities to fix'
|
|
25
26
|
: "No major issues, here's what we found";
|
|
26
27
|
console.log(chalk_1.default.bold(message));
|
|
27
28
|
console.log();
|
|
28
|
-
|
|
29
|
+
const defaultView = getDefaultView(content, language);
|
|
29
30
|
let count = 0;
|
|
30
31
|
defaultView.forEach(entry => {
|
|
31
32
|
count++;
|
|
32
|
-
|
|
33
|
+
const table = new cli_table3_1.default({
|
|
33
34
|
chars: {
|
|
34
35
|
top: '',
|
|
35
36
|
'top-mid': '',
|
|
@@ -90,8 +91,8 @@ function formatScanOutput(scanResults) {
|
|
|
90
91
|
console.log();
|
|
91
92
|
});
|
|
92
93
|
}
|
|
93
|
-
(0, commonReportingFunctions_1.printVulnInfo)(
|
|
94
|
-
return
|
|
94
|
+
(0, commonReportingFunctions_1.printVulnInfo)(severityCounts);
|
|
95
|
+
return severityCounts;
|
|
95
96
|
}
|
|
96
97
|
exports.formatScanOutput = formatScanOutput;
|
|
97
98
|
function formatLinks(objName, entry) {
|
|
@@ -107,7 +108,7 @@ function formatLinks(objName, entry) {
|
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
exports.formatLinks = formatLinks;
|
|
110
|
-
function getDefaultView(content) {
|
|
111
|
+
function getDefaultView(content, language) {
|
|
111
112
|
const groupTypeResults = [];
|
|
112
113
|
content.forEach(resultEntry => {
|
|
113
114
|
const groupResultsObj = new groupedResultsModel_1.GroupedResultsModel(resultEntry.ruleId);
|
|
@@ -118,8 +119,7 @@ function getDefaultView(content) {
|
|
|
118
119
|
groupResultsObj.learn = resultEntry.learn;
|
|
119
120
|
groupResultsObj.message = resultEntry.message?.text
|
|
120
121
|
? editVulName(resultEntry.message.text) +
|
|
121
|
-
|
|
122
|
-
getSourceLineNumber(resultEntry)
|
|
122
|
+
doAddSourceLineNumber(resultEntry, language)
|
|
123
123
|
: '';
|
|
124
124
|
groupResultsObj.codePath = getLocationsSyncInfo(resultEntry);
|
|
125
125
|
groupTypeResults.push(groupResultsObj);
|
|
@@ -128,6 +128,12 @@ function getDefaultView(content) {
|
|
|
128
128
|
return (0, lodash_1.sortBy)(groupTypeResults, ['priority']);
|
|
129
129
|
}
|
|
130
130
|
exports.getDefaultView = getDefaultView;
|
|
131
|
+
function doAddSourceLineNumber(resultEntry, language) {
|
|
132
|
+
return language !== constants_1.supportedLanguagesScan.JAVASCRIPT
|
|
133
|
+
? ':' + getSourceLineNumber(resultEntry)
|
|
134
|
+
: '';
|
|
135
|
+
}
|
|
136
|
+
exports.doAddSourceLineNumber = doAddSourceLineNumber;
|
|
131
137
|
function editVulName(message) {
|
|
132
138
|
return message.substring(message.indexOf(' in '));
|
|
133
139
|
}
|
|
@@ -143,7 +149,7 @@ function getLocationsSyncInfo(resultEntry) {
|
|
|
143
149
|
exports.getLocationsSyncInfo = getLocationsSyncInfo;
|
|
144
150
|
function getSourceLineNumber(resultEntry) {
|
|
145
151
|
const locationsLineNumber = resultEntry.locations[0]?.physicalLocation?.region?.startLine || '';
|
|
146
|
-
|
|
152
|
+
const codeFlowLineNumber = getCodeFlowInfo(resultEntry);
|
|
147
153
|
return codeFlowLineNumber ? codeFlowLineNumber : locationsLineNumber;
|
|
148
154
|
}
|
|
149
155
|
exports.getSourceLineNumber = getSourceLineNumber;
|
|
@@ -15,15 +15,4 @@ const getAuth = () => {
|
|
|
15
15
|
}
|
|
16
16
|
return ContrastConfToUse;
|
|
17
17
|
};
|
|
18
|
-
|
|
19
|
-
const ContrastConf = config.localConfig(APP_NAME, APP_VERSION);
|
|
20
|
-
let ContrastConfToUse = {};
|
|
21
|
-
ContrastConfToUse.javaAgreement = ContrastConf.get('javaAgreement');
|
|
22
|
-
return ContrastConfToUse;
|
|
23
|
-
};
|
|
24
|
-
const setAgreement = agreement => {
|
|
25
|
-
const ContrastConf = config.localConfig(APP_NAME, APP_VERSION);
|
|
26
|
-
ContrastConf.set('javaAgreement', agreement);
|
|
27
|
-
return agreement;
|
|
28
|
-
};
|
|
29
|
-
module.exports = { getAuth, getAgreement, setAgreement };
|
|
18
|
+
module.exports = { getAuth };
|
|
@@ -22,10 +22,4 @@ const getAuth = params => {
|
|
|
22
22
|
process.exit(1);
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
|
-
|
|
26
|
-
return configStoreParams.getAgreement();
|
|
27
|
-
};
|
|
28
|
-
const setAgreement = answer => {
|
|
29
|
-
return configStoreParams.setAgreement(answer);
|
|
30
|
-
};
|
|
31
|
-
module.exports = { getAuth, getAgreement, setAgreement };
|
|
25
|
+
module.exports = { getAuth };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/contrast",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.20",
|
|
4
4
|
"description": "Contrast Security's command line tool",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
{
|
|
16
16
|
"name": "Andrew Shanks",
|
|
17
17
|
"email": "andrew.shanks@contrastsecurity.com"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "Oisín Cassidy",
|
|
21
|
+
"email": "oisin.cassidy@contrastsecurity.com"
|
|
18
22
|
}
|
|
19
23
|
],
|
|
20
24
|
"license": "ISC",
|
|
@@ -108,7 +108,8 @@ const printFormattedOutput = (
|
|
|
108
108
|
new SeverityCountModel()
|
|
109
109
|
).getTotal
|
|
110
110
|
),
|
|
111
|
-
library.cveArray
|
|
111
|
+
library.cveArray,
|
|
112
|
+
null
|
|
112
113
|
)
|
|
113
114
|
report.reportOutputList.push(newOutputModel)
|
|
114
115
|
}
|
|
@@ -131,6 +132,7 @@ const printFormattedOutput = (
|
|
|
131
132
|
contrastHeaderNumCounter++
|
|
132
133
|
const { libraryName, libraryVersion, highestSeverity } =
|
|
133
134
|
reportModel.compositeKey
|
|
135
|
+
|
|
134
136
|
const numOfCVEs = reportModel.cveArray.length
|
|
135
137
|
|
|
136
138
|
const table = getReportTable()
|
|
@@ -236,9 +238,11 @@ function buildHeader(
|
|
|
236
238
|
}
|
|
237
239
|
|
|
238
240
|
function buildBody(cveArray, advice) {
|
|
239
|
-
|
|
241
|
+
const orderedCvesWithSeverityAssigned = orderByHighestPriority(
|
|
242
|
+
cveArray.map(cve => findCVESeverity(cve))
|
|
243
|
+
)
|
|
240
244
|
|
|
241
|
-
const issueMessage = getIssueRow(
|
|
245
|
+
const issueMessage = getIssueRow(orderedCvesWithSeverityAssigned)
|
|
242
246
|
|
|
243
247
|
//todo different advice based on remediationGuidance being available or now
|
|
244
248
|
// console.log(advice)
|
|
@@ -254,7 +258,6 @@ function buildBody(cveArray, advice) {
|
|
|
254
258
|
}
|
|
255
259
|
|
|
256
260
|
function getIssueRow(cveArray) {
|
|
257
|
-
orderByHighestPriority(cveArray)
|
|
258
261
|
const cveMessagesList = getIssueCveMsgList(cveArray)
|
|
259
262
|
return [chalk.bold('Issue'), ':', `${cveMessagesList.join(', ')}`]
|
|
260
263
|
}
|
|
@@ -301,7 +304,6 @@ const getIssueCveMsgList = results => {
|
|
|
301
304
|
const cveMessages = []
|
|
302
305
|
|
|
303
306
|
results.forEach(reportSeverityModel => {
|
|
304
|
-
// @ts-ignore
|
|
305
307
|
const { colour, severity, name } = reportSeverityModel
|
|
306
308
|
|
|
307
309
|
const severityShorthand = chalk
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { ReportSeverityModel } from './reportSeverityModel'
|
|
2
2
|
import { ReportCVEModel } from './reportLibraryModel'
|
|
3
|
+
import {
|
|
4
|
+
ScaReportRemediationAdviceModel,
|
|
5
|
+
ScaReportVulnerabilityModel
|
|
6
|
+
} from '../../../scaAnalysis/common/models/ScaReportModel'
|
|
3
7
|
|
|
4
8
|
export class ReportList {
|
|
5
9
|
reportOutputList: ReportModelStructure[]
|
|
@@ -11,11 +15,17 @@ export class ReportList {
|
|
|
11
15
|
|
|
12
16
|
export class ReportModelStructure {
|
|
13
17
|
compositeKey: ReportCompositeKey
|
|
14
|
-
cveArray: ReportCVEModel[]
|
|
18
|
+
cveArray: ReportCVEModel[] | ScaReportVulnerabilityModel[]
|
|
19
|
+
remediationAdvice: ScaReportRemediationAdviceModel | null
|
|
15
20
|
|
|
16
|
-
constructor(
|
|
21
|
+
constructor(
|
|
22
|
+
compositeKey: ReportCompositeKey,
|
|
23
|
+
cveArray: ReportCVEModel[] | ScaReportVulnerabilityModel[],
|
|
24
|
+
remediationAdvice: ScaReportRemediationAdviceModel | null
|
|
25
|
+
) {
|
|
17
26
|
this.compositeKey = compositeKey
|
|
18
27
|
this.cveArray = cveArray
|
|
28
|
+
this.remediationAdvice = remediationAdvice
|
|
19
29
|
}
|
|
20
30
|
}
|
|
21
31
|
|
|
@@ -87,7 +87,7 @@ export async function vulnerabilityReportV2(config: any, reportId: string) {
|
|
|
87
87
|
const reportResponse = await getReport(config, reportId)
|
|
88
88
|
|
|
89
89
|
if (reportResponse !== undefined) {
|
|
90
|
-
|
|
90
|
+
const output = formatVulnerabilityOutput(
|
|
91
91
|
reportResponse.vulnerabilities,
|
|
92
92
|
config.applicationId,
|
|
93
93
|
config,
|
|
@@ -3,8 +3,7 @@ import {
|
|
|
3
3
|
ReportLibraryModel
|
|
4
4
|
} from '../models/reportLibraryModel'
|
|
5
5
|
import { ReportSeverityModel } from '../models/reportSeverityModel'
|
|
6
|
-
import languageAnalysisEngine
|
|
7
|
-
import {
|
|
6
|
+
import languageAnalysisEngine, {
|
|
8
7
|
CRITICAL_COLOUR,
|
|
9
8
|
CRITICAL_PRIORITY,
|
|
10
9
|
HIGH_COLOUR,
|
|
@@ -19,6 +18,7 @@ import {
|
|
|
19
18
|
import { orderBy } from 'lodash'
|
|
20
19
|
import { SeverityCountModel } from '../models/severityCountModel'
|
|
21
20
|
import { ReportModelStructure } from '../models/reportListModel'
|
|
21
|
+
|
|
22
22
|
const {
|
|
23
23
|
supportedLanguages: { GO }
|
|
24
24
|
} = languageAnalysisEngine
|
|
@@ -30,8 +30,8 @@ export function findHighestSeverityCVE(cveArray: ReportCVEModel[]) {
|
|
|
30
30
|
return orderBy(mappedToReportSeverityModels, cve => cve?.priority)[0]
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export function orderByHighestPriority(
|
|
34
|
-
return orderBy(
|
|
33
|
+
export function orderByHighestPriority(severityModels: ReportSeverityModel[]) {
|
|
34
|
+
return orderBy(severityModels, ['priority'], ['asc'])
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export function findCVESeverity(cve: ReportCVEModel) {
|
|
@@ -10,8 +10,7 @@ const getAuditConfig = async (contrastConf, command, argv) => {
|
|
|
10
10
|
constants.commandLineDefinitions.auditOptionDefinitions
|
|
11
11
|
)
|
|
12
12
|
const paramsAuth = paramHandler.getAuth(auditParameters)
|
|
13
|
-
|
|
14
|
-
return { ...paramsAuth, ...auditParameters, ...javaAgreement }
|
|
13
|
+
return { ...paramsAuth, ...auditParameters }
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
module.exports = {
|
|
@@ -33,6 +33,9 @@ const scaUpload = require('../../../scaAnalysis/common/scaServicesUpload')
|
|
|
33
33
|
const settingsHelper = require('../../../utils/settingsHelper')
|
|
34
34
|
const chalk = require('chalk')
|
|
35
35
|
const saveResults = require('../../../scan/saveResults')
|
|
36
|
+
const {
|
|
37
|
+
convertGenericToTypedReportModelSca
|
|
38
|
+
} = require('../../../scaAnalysis/common/utils/reportUtilsSca')
|
|
36
39
|
|
|
37
40
|
const processSca = async config => {
|
|
38
41
|
//checks to see whether to use old TS / new SCA path
|
|
@@ -133,12 +136,14 @@ const processSca = async config => {
|
|
|
133
136
|
console.log('') //empty log for space before spinner
|
|
134
137
|
const reportSpinner = returnOra(i18n.__('auditSCAAnalysisBegins'))
|
|
135
138
|
startSpinner(reportSpinner)
|
|
136
|
-
const
|
|
139
|
+
const { reportArray, reportId } = await scaUpload.scaTreeUpload(
|
|
137
140
|
messageToSend,
|
|
138
141
|
config
|
|
139
142
|
)
|
|
140
143
|
|
|
141
|
-
|
|
144
|
+
const reportModelLibraryList =
|
|
145
|
+
convertGenericToTypedReportModelSca(reportArray)
|
|
146
|
+
auditReport.processAuditReport(config, reportModelLibraryList)
|
|
142
147
|
succeedSpinner(reportSpinner, i18n.__('auditSCAAnalysisComplete'))
|
|
143
148
|
|
|
144
149
|
if (config.save !== undefined) {
|
package/src/constants/locales.js
CHANGED
|
@@ -194,7 +194,10 @@ const en_locales = () => {
|
|
|
194
194
|
chalk.bold('\ncontrast scan') +
|
|
195
195
|
" to run Contrast's industry leading SAST scanner. \nSupports Java, JavaScript and .Net \n" +
|
|
196
196
|
chalk.bold('\ncontrast audit') +
|
|
197
|
-
' to find vulnerabilities in your open source dependencies
|
|
197
|
+
' to find vulnerabilities in your open source dependencies.' +
|
|
198
|
+
'\nSupports Java, .NET, Node, Ruby, Python, Go and PHP.' +
|
|
199
|
+
'\nOur CLI runs native build tools to generate a complete dependency tree.' +
|
|
200
|
+
'\nIf you are running on untrusted code, consider running in a sandbox.\n' +
|
|
198
201
|
chalk.bold('\ncontrast lambda') +
|
|
199
202
|
' to secure your AWS serverless functions. \nSupports Java and Python \n' +
|
|
200
203
|
chalk.bold('\ncontrast help') +
|
|
@@ -259,7 +262,8 @@ const en_locales = () => {
|
|
|
259
262
|
)} Maven build platform including the dependency plugin.
|
|
260
263
|
${chalk.bold('Or')} build.gradle ${chalk.bold(
|
|
261
264
|
'and'
|
|
262
|
-
)} gradle dependencies or ./gradlew dependencies must be supported
|
|
265
|
+
)} gradle dependencies or ./gradlew dependencies must be supported
|
|
266
|
+
If you are running on untrusted code, consider running in a sandbox.`,
|
|
263
267
|
constantsAuditPrerequisitesContentDotNetMessage: `
|
|
264
268
|
${chalk.bold(
|
|
265
269
|
'.NET framework and .NET core:'
|
|
@@ -1,105 +1,50 @@
|
|
|
1
1
|
const {
|
|
2
2
|
getSeverityCounts,
|
|
3
|
-
createSummaryMessageTop,
|
|
4
|
-
printVulnInfo,
|
|
5
|
-
getReportTable,
|
|
6
|
-
getIssueRow,
|
|
7
3
|
printNoVulnFoundMsg
|
|
8
4
|
} = require('../../audit/report/commonReportingFunctions')
|
|
9
|
-
const { orderBy } = require('lodash')
|
|
10
|
-
const { assignBySeverity } = require('../../scan/formatScanOutput')
|
|
11
|
-
const chalk = require('chalk')
|
|
12
|
-
const { CE_URL } = require('../../constants/constants')
|
|
13
5
|
const common = require('../../common/fail')
|
|
14
|
-
const
|
|
6
|
+
const { printFormattedOutputSca } = require('./commonReportingFunctionsSca')
|
|
15
7
|
|
|
16
|
-
const processAuditReport = (config,
|
|
8
|
+
const processAuditReport = (config, reportModelList) => {
|
|
17
9
|
let severityCounts = {}
|
|
18
|
-
if (
|
|
19
|
-
severityCounts = formatScaServicesReport(config,
|
|
10
|
+
if (reportModelList !== undefined) {
|
|
11
|
+
severityCounts = formatScaServicesReport(config, reportModelList)
|
|
20
12
|
}
|
|
21
13
|
|
|
22
14
|
if (config.fail) {
|
|
23
15
|
common.processFail(config, severityCounts)
|
|
24
16
|
}
|
|
25
17
|
}
|
|
26
|
-
const formatScaServicesReport = (config,
|
|
27
|
-
const projectOverviewCount = getSeverityCounts(
|
|
18
|
+
const formatScaServicesReport = (config, reportModelList) => {
|
|
19
|
+
const projectOverviewCount = getSeverityCounts(reportModelList)
|
|
28
20
|
|
|
29
21
|
if (projectOverviewCount.total === 0) {
|
|
30
22
|
printNoVulnFoundMsg()
|
|
31
|
-
return projectOverviewCount
|
|
32
23
|
} else {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const table = getReportTable()
|
|
36
|
-
let contrastHeaderNumCounter = 0
|
|
37
|
-
let assignPriorityToResults = results.map(result =>
|
|
38
|
-
assignBySeverity(result, result)
|
|
39
|
-
)
|
|
40
|
-
const numberOfVulns = results
|
|
41
|
-
.map(result => result.vulnerabilities)
|
|
42
|
-
.reduce((a, b) => {
|
|
43
|
-
return (total += b.length)
|
|
44
|
-
}, 0)
|
|
45
|
-
const outputOrderedByLowestSeverityAndLowestNumOfCvesFirst = orderBy(
|
|
46
|
-
assignPriorityToResults,
|
|
47
|
-
[
|
|
48
|
-
reportListItem => {
|
|
49
|
-
return reportListItem.priority
|
|
50
|
-
},
|
|
51
|
-
reportListItem => {
|
|
52
|
-
return reportListItem.vulnerabilities.length
|
|
53
|
-
}
|
|
54
|
-
],
|
|
55
|
-
['asc', 'desc']
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
for (const result of outputOrderedByLowestSeverityAndLowestNumOfCvesFirst) {
|
|
59
|
-
contrastHeaderNumCounter++
|
|
60
|
-
const cvesNum = result.vulnerabilities.length
|
|
61
|
-
const grammaticallyCorrectVul =
|
|
62
|
-
result.vulnerabilities.length > 1 ? 'vulnerabilities' : 'vulnerability'
|
|
63
|
-
|
|
64
|
-
const headerColour = chalk.hex(result.colour)
|
|
65
|
-
const headerRow = [
|
|
66
|
-
headerColour(
|
|
67
|
-
`CONTRAST-${contrastHeaderNumCounter.toString().padStart(3, '0')}`
|
|
68
|
-
),
|
|
69
|
-
headerColour(`-`),
|
|
70
|
-
headerColour(`[${result.severity}] `) +
|
|
71
|
-
headerColour.bold(`${result.artifactName}`) +
|
|
72
|
-
` introduces ${cvesNum} ${grammaticallyCorrectVul}`
|
|
73
|
-
]
|
|
24
|
+
const numberOfVulnerableLibraries = reportModelList.map(library => {
|
|
25
|
+
let count = 0
|
|
74
26
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
`Change to version ${result.remediationAdvice.latestStableVersion}`
|
|
79
|
-
]
|
|
27
|
+
if (library.vulnerabilities.length > 0) {
|
|
28
|
+
count++
|
|
29
|
+
}
|
|
80
30
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
)
|
|
84
|
-
const issueRow = getIssueRow(assignPriorityToVulns)
|
|
31
|
+
return count
|
|
32
|
+
}).length
|
|
85
33
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
console.log()
|
|
91
|
-
createSummaryMessageTop(numberOfCves, numberOfVulns)
|
|
92
|
-
console.log(table.toString() + '\n')
|
|
93
|
-
printVulnInfo(projectOverviewCount)
|
|
34
|
+
let numberOfCves = reportModelList.reduce(
|
|
35
|
+
(count, current) => count + current.vulnerabilities.length,
|
|
36
|
+
0
|
|
37
|
+
)
|
|
94
38
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return projectOverviewCount
|
|
39
|
+
printFormattedOutputSca(
|
|
40
|
+
config,
|
|
41
|
+
reportModelList,
|
|
42
|
+
numberOfVulnerableLibraries,
|
|
43
|
+
numberOfCves
|
|
44
|
+
)
|
|
102
45
|
}
|
|
46
|
+
|
|
47
|
+
return projectOverviewCount
|
|
103
48
|
}
|
|
104
49
|
module.exports = {
|
|
105
50
|
formatScaServicesReport,
|